package voter

import "context"

// StrategyUnanimous returns Allow if all voters allow the operations.
func StrategyUnanimous(ctx context.Context, decisions []Decision) (Decision, error) {
	allAbstains := true

	for _, d := range decisions {
		if d == Deny {
			return Deny, nil
		}

		if d != Abstain {
			allAbstains = false
		}
	}

	if allAbstains {
		return Abstain, nil
	}

	return Allow, nil
}

// StrategyAffirmative returns Allow if at least one voter allow the operation.
func StrategyAffirmative(ctx context.Context, decisions []Decision) (Decision, error) {
	allAbstains := true

	for _, d := range decisions {
		if d == Allow {
			return Allow, nil
		}

		if allAbstains && d != Abstain {
			allAbstains = false
		}
	}

	if allAbstains {
		return Abstain, nil
	}

	return Deny, nil
}

// StrategyConsensus returns Allow if the majority of voters allow the operation.
func StrategyConsensus(ctx context.Context, decisions []Decision) (Decision, error) {
	deny := 0
	allow := 0
	abstain := 0

	for _, d := range decisions {
		switch {
		case d == Allow:
			allow++
		case d == Deny:
			deny++
		case d == Abstain:
			abstain++
		}
	}

	if abstain > allow && abstain > deny {
		return Abstain, nil
	}

	if allow > abstain && allow > deny {
		return Allow, nil
	}

	if deny > allow && deny > abstain {
		return Deny, nil
	}

	return Abstain, nil
}