package placement

import (
	"errors"
	"strings"

	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
)

const (
	attrPrefix = "$attribute:"
)

type Metric interface {
	CalculateValue(*netmap.NodeInfo, *netmap.NodeInfo) int
}

func ParseMetric(raw string) (Metric, error) {
	if attr, found := strings.CutPrefix(raw, attrPrefix); found {
		return NewAttributeMetric(attr), nil
	}
	return nil, errors.New("unsupported priority metric")
}

// attributeMetric describes priority metric based on attribute.
type attributeMetric struct {
	attribute string
}

// CalculateValue return [0] if from and to contains attribute attributeMetric.attribute and
// the value of attribute is the same. In other case return [1].
func (am *attributeMetric) CalculateValue(from *netmap.NodeInfo, to *netmap.NodeInfo) int {
	fromAttr := from.Attribute(am.attribute)
	toAttr := to.Attribute(am.attribute)
	if len(fromAttr) > 0 && len(toAttr) > 0 && fromAttr == toAttr {
		return 0
	}
	return 1
}

func NewAttributeMetric(attr string) Metric {
	return &attributeMetric{attribute: attr}
}