using System;
using System.Collections.Concurrent;
using System.Reflection;

namespace JiShe.CollectBus.Analyzers.Shared;

public static class SourceEntityAccessorFactory3
{
    private static readonly ConcurrentDictionary<Type, object> _accessors = new();

    public static ISourceEntityAccessor<T> GetAccessor<T>()
    {
        return (ISourceEntityAccessor<T>)_accessors.GetOrAdd(typeof(T), t =>
        {
            // 获取泛型类型定义信息（如果是泛型类型）
            var isGeneric = t.IsGenericType;
            var genericTypeDef = isGeneric ? t.GetGenericTypeDefinition() : null;
            var arity = isGeneric ? genericTypeDef!.GetGenericArguments().Length : 0;

            // 构建访问器类名
            var typeName = isGeneric
                ? $"{t.Namespace}.{genericTypeDef!.Name.Split('`')[0]}Accessor`{arity}"
                : $"{t.Namespace}.{t.Name}Accessor";

            // 尝试从当前程序集加载
            var accessorType = Assembly.GetAssembly(t)!.GetType(typeName)
                ?? throw new InvalidOperationException($"Accessor type {typeName} not found");

            // 处理泛型参数
            if (isGeneric && accessorType.IsGenericTypeDefinition)
            {
                accessorType = accessorType.MakeGenericType(t.GetGenericArguments());
            }

            return Activator.CreateInstance(accessorType)!;
        });
    }

    public static object GetAccessor(Type type)
    {
        MethodInfo getAccessorMethod = typeof(SourceEntityAccessorFactory)
            .GetMethod(
                name: nameof(GetAccessor),
                bindingAttr: BindingFlags.Public | BindingFlags.Static,

                types: Type.EmptyTypes
            );

        MethodInfo genericMethod = getAccessorMethod.MakeGenericMethod(type);
        return genericMethod.Invoke(null, null);
    }
}