using System;
using System.Collections.Generic;
using System.Linq;
using NodePipeline.Configuration.Abstractions.Models.Edit;
using NodePipeline.Configuration.Abstractions.Models.Execute;

namespace NodePipeline.Configuration.Abstractions;

public static class EditorToRuntimePipelineConverter
{
    public static PipelineConfig ToRuntime(EditorPipelineConfig editor)
    {
        var nodes = new List<NodeConfig>(editor.Nodes
            .Sum(x => x.Parameters.Count + x.Inputs.Count + x.Outputs.Count));
        foreach (var node in editor.Nodes)
        {
            var parameters = node.Parameters
                .Where(q => q.Value.Value is not null)
                .ToDictionary(kv => kv.Key, kv => kv.Value.Value!);
            var inputs = new Dictionary<string, InputSource>();
            foreach (var input in node.Inputs)
                if (TryParseInputSource(input.Value?.Source, out var inputSource) && inputSource != null)
                    inputs.Add(input.Key, inputSource);

            nodes.Add(new NodeConfig
            {
                Id = node.Id,
                Type = node.Type,
                Parameters = parameters,
                Inputs = inputs,
                Outputs = [..node.Outputs.Keys]
            });
        }

        return new PipelineConfig
        {
            Name = editor.Name,
            Nodes = nodes
        };
    }

    private static bool TryParseInputSource(string? source, out InputSource? inputSource)
    {
        if (string.IsNullOrWhiteSpace(source))
        {
            inputSource = null;
            return false;
        }

        var arr = source!
            .Split(['.'], StringSplitOptions.RemoveEmptyEntries)
            .Select(s => s.Trim())
            .ToArray();
        if (arr.Length != 2)
        {
            inputSource = null;
            return false;
        }

        inputSource = new InputSource
        {
            NodeId = arr[0],
            OutputName = arr[1]
        };
        return true;
    }
}