using Sdt.Config;

namespace Sdt.Core;

public sealed class WorkflowPlanner : IWorkflowPlanner
{
    public List<WorkflowDefinition> ResolvePlan(
        WorkflowDefinition workflow,
        IReadOnlyDictionary<string, WorkflowDefinition> allWorkflows)
    {
        var visited = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        var plan = new List<WorkflowDefinition>();
        Visit(workflow, allWorkflows, visited, plan);
        return plan;
    }

    private static void Visit(
        WorkflowDefinition workflow,
        IReadOnlyDictionary<string, WorkflowDefinition> allWorkflows,
        HashSet<string> visited,
        List<WorkflowDefinition> plan)
    {
        if (!visited.Add(workflow.Id))
            return;

        foreach (var depId in workflow.DependsOn)
        {
            if (allWorkflows.TryGetValue(depId, out var dep))
                Visit(dep, allWorkflows, visited, plan);
        }

        if (workflow.Steps.Count > 0)
            plan.Add(workflow);
    }
}
