using Sdt.Core;

namespace Sdt.Config;

public enum LegacyMode
{
    Strict,
    Compat,
}

public sealed record WorkflowNormalizationResult(
    IReadOnlyList<WorkflowDefinition> Workflows,
    IReadOnlyList<string> Warnings);

public static class WorkflowModelBuilder
{
    public static WorkflowNormalizationResult Normalize(
        DevToolConfig config,
        LegacyMode legacyMode = LegacyMode.Strict,
        IRequirementResolver? requirementResolver = null)
    {
        requirementResolver ??= new RequirementResolver();
        var warnings = new List<string>();

        if (config.Workflows.Count > 0)
        {
            if (config.Targets.Count > 0)
            {
                warnings.Add("Both 'workflows' and legacy 'targets' are present. SDT will use 'workflows'.");
            }

            return new WorkflowNormalizationResult(config.Workflows, warnings);
        }

        if (config.Targets.Count == 0)
        {
            warnings.Add("No 'workflows' or legacy 'targets' were found.");
            return new WorkflowNormalizationResult([], warnings);
        }

        if (legacyMode == LegacyMode.Strict)
        {
            throw new InvalidOperationException(
                "Legacy 'targets' are not allowed in strict mode. Migrate to 'workflows' or set SDT_LEGACY_MODE=compat temporarily.");
        }

        warnings.Add("Using legacy 'targets' schema. Migrate to 'workflows' for v1+ features.");
        return new WorkflowNormalizationResult(ConvertLegacyTargets(config.Targets, requirementResolver), warnings);
    }

    public static DevToolConfig BuildMigrationPreviewConfig(DevToolConfig config, IRequirementResolver? requirementResolver = null)
    {
        requirementResolver ??= new RequirementResolver();
        return new DevToolConfig
        {
            Name = config.Name,
            Version = config.Version,
            Targets = [],
            Workflows = ConvertLegacyTargets(config.Targets, requirementResolver),
            Env = config.Env,
            Toolchains = config.Toolchains,
            Tooling = config.Tooling,
            Project = config.Project,
            Debug = config.Debug,
        };
    }

    private static List<WorkflowDefinition> ConvertLegacyTargets(
        IReadOnlyList<BuildTarget> targets,
        IRequirementResolver requirementResolver)
    {
        var workflows = new List<WorkflowDefinition>(targets.Count);
        foreach (var target in targets)
        {
            var step = target.Command is null
                ? null
                : new WorkflowStep
                {
                    Id = $"{target.Id}:run",
                    Label = string.IsNullOrWhiteSpace(target.Label) ? target.Id : target.Label,
                    Command = target.Command,
                    Args = target.Args,
                    WorkingDir = target.WorkingDir,
                    Requires = requirementResolver.Resolve(target),
                };

            workflows.Add(new WorkflowDefinition
            {
                Id = target.Id,
                Label = target.Label,
                Description = target.Description,
                Group = target.Group,
                DependsOn = target.DependsOn,
                Steps = step is null ? [] : [step],
            });
        }

        return workflows;
    }
}
