package policer

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

type nodeProcessStatus int8

const (
	nodeNotProcessed nodeProcessStatus = iota
	nodeDoesNotHoldObject
	nodeHoldsObject
)

func (st nodeProcessStatus) Processed() bool {
	return st != nodeNotProcessed
}

// nodeCache tracks Policer's check progress.
type nodeCache map[uint64]bool

func newNodeCache() nodeCache {
	return make(map[uint64]bool)
}

func (n nodeCache) set(node netmap.NodeInfo, val bool) {
	n[node.Hash()] = val
}

// submits storage node as a candidate to store the object replica in case of
// shortage.
func (n nodeCache) submitReplicaCandidate(node netmap.NodeInfo) {
	n.set(node, false)
}

// submits storage node as a current object replica holder.
func (n nodeCache) submitReplicaHolder(node netmap.NodeInfo) {
	n.set(node, true)
}

// processStatus returns current processing status of the storage node.
func (n nodeCache) processStatus(node netmap.NodeInfo) nodeProcessStatus {
	switch val, ok := n[node.Hash()]; {
	case !ok:
		return nodeNotProcessed
	case val:
		return nodeHoldsObject
	default:
		return nodeDoesNotHoldObject
	}
}

// SubmitSuccessfulReplication marks given storage node as a current object
// replica holder.
//
// SubmitSuccessfulReplication implements replicator.TaskResult.
func (n nodeCache) SubmitSuccessfulReplication(node netmap.NodeInfo) {
	n.submitReplicaHolder(node)
}