using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Beam {
    /// <summary>
    /// Source-style type name (e.g. Foo&lt;T&gt;, Dictionary&lt;int,string&gt;[,], Span&lt;byte&gt;*, MyClass.Nested).
    /// </summary>
    public static class TypeExtensions {
        public static string AsUniqueName(this Type type) {
            if (type.IsGenericParameter)
                return type.Name;

            if (type.IsArray) {
                var commas = new string(',', type.GetArrayRank() - 1);
                return $"{type.GetElementType().AsUniqueName()}[{commas}]";
            }

            if (type.IsPointer)
                return $"{type.GetElementType().AsUniqueName()}*";

            if (type.IsByRef)
                return $"{type.GetElementType().AsUniqueName()}&";

            if (type.IsNested && !type.IsGenericParameter)
                return $"{type.DeclaringType!.AsUniqueName()}.{BuildSimpleName(type)}";

            return BuildSimpleName(type);

            static string BuildSimpleName(Type t) {
                if (!t.IsGenericType) return t.Name;

                var baseName = t.Name[..t.Name.IndexOf('`')];
                var args = t.GetGenericArguments().Select(AsUniqueName);
                return $"{baseName}<{string.Join(", ", args)}>";
            }
        }
    }
}
