namespace NubLang.Syntax;

public sealed class Module
{
    public static Dictionary<string, Module> Collect(List<SyntaxTree> syntaxTrees)
    {
        var modules = new Dictionary<string, Module>();
        foreach (var syntaxTree in syntaxTrees)
        {
            var moduleDeclaration = syntaxTree.TopLevelSyntaxNodes.OfType<ModuleSyntax>().FirstOrDefault();
            if (moduleDeclaration != null)
            {
                if (!modules.TryGetValue(moduleDeclaration.NameToken.Value, out var module))
                {
                    module = new Module();
                    modules.Add(moduleDeclaration.NameToken.Value, module);
                }

                module._definitions.AddRange(syntaxTree.TopLevelSyntaxNodes);
            }
        }

        return modules;
    }

    private readonly List<TopLevelSyntaxNode> _definitions = [];

    public List<StructSyntax> Structs(bool includePrivate)
    {
        return _definitions
            .OfType<StructSyntax>()
            .Where(x => x.Exported || includePrivate)
            .ToList();
    }

    public List<FuncSyntax> Functions(bool includePrivate)
    {
        return _definitions
            .OfType<FuncSyntax>()
            .Where(x => x.Exported || includePrivate)
            .ToList();
    }

    public List<EnumSyntax> Enums(bool includePrivate)
    {
        return _definitions
            .OfType<EnumSyntax>()
            .Where(x => x.Exported || includePrivate)
            .ToList();
    }

    public List<string> Imports()
    {
        return _definitions
            .OfType<ImportSyntax>()
            .Select(x => x.NameToken.Value)
            .Distinct()
            .ToList();
    }
}