package graph_path_finder

import (
	"github.com/tech/sendico/payments/storage/model"
	"github.com/tech/sendico/pkg/discovery"
	"github.com/tech/sendico/pkg/merrors"
)

type GraphPathFinder struct{}

func New() *GraphPathFinder {
	return &GraphPathFinder{}
}

type normalizedEdge struct {
	from    model.Rail
	to      model.Rail
	network string
}

type score struct {
	hops         int
	wildcardHops int
	signature    string
}

func (f *GraphPathFinder) Find(in FindInput) (*Path, error) {
	source := normalizeRail(in.SourceRail)
	destination := normalizeRail(in.DestinationRail)
	if source == discovery.RailUnspecified {
		return nil, merrors.InvalidArgument("source_rail is required")
	}
	if destination == discovery.RailUnspecified {
		return nil, merrors.InvalidArgument("destination_rail is required")
	}
	if source == destination {
		return &Path{Rails: []model.Rail{source}}, nil
	}

	network := normalizeNetwork(in.Network)
	adjacency := buildAdjacency(in.Edges, network)
	if len(adjacency) == 0 {
		return nil, merrors.InvalidArgument("route graph has no usable edges")
	}

	path, ok := shortestPath(source, destination, network, adjacency)
	if !ok {
		return nil, merrors.InvalidArgument("route path is unavailable")
	}
	return path, nil
}
