package graph_path_finder

import (
	"github.com/tech/sendico/pkg/discovery"
	"sort"
	"strings"

	"github.com/tech/sendico/payments/storage/model"
)

func buildAdjacency(edges []Edge, network string) map[model.Rail][]normalizedEdge {
	adjacency := map[model.Rail][]normalizedEdge{}
	for _, edge := range edges {
		from := normalizeRail(edge.FromRail)
		to := normalizeRail(edge.ToRail)
		if from == discovery.RailUnspecified || to == discovery.RailUnspecified {
			continue
		}
		en := normalizeNetwork(edge.Network)
		if !matchesNetwork(en, network) {
			continue
		}
		adjacency[from] = append(adjacency[from], normalizedEdge{
			from:    from,
			to:      to,
			network: en,
		})
	}
	for from := range adjacency {
		sort.Slice(adjacency[from], func(i, j int) bool {
			left := adjacency[from][i]
			right := adjacency[from][j]
			if left.to != right.to {
				return left.to < right.to
			}
			lp := networkPriority(left.network, network)
			rp := networkPriority(right.network, network)
			if lp != rp {
				return lp < rp
			}
			return left.network < right.network
		})
	}
	return adjacency
}

func matchesNetwork(edgeNetwork, requested string) bool {
	if requested == "" {
		return true
	}
	if edgeNetwork == "" {
		return true
	}
	return edgeNetwork == requested
}

func networkPriority(edgeNetwork, requested string) int {
	if requested != "" && edgeNetwork == requested {
		return 0
	}
	if edgeNetwork == "" {
		return 1
	}
	return 2
}

func normalizeRail(value model.Rail) model.Rail {
	normalized := model.ParseRail(string(value))
	if normalized == discovery.RailUnspecified {
		return discovery.RailUnspecified
	}
	return normalized
}

func normalizeNetwork(value string) string {
	return strings.ToUpper(strings.TrimSpace(value))
}
