using IpcLibrary.Core;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace IpcLibrary.Services {
    /// <summary>
    /// 服务注册器实现
    /// </summary>
    public class ServiceRegistry : IServiceRegistry {
        private readonly ConcurrentDictionary<string, ServiceInfo> _services;
        private readonly object _lock = new object();

        public ServiceRegistry() {
            _services = new ConcurrentDictionary<string, ServiceInfo>();
        }

        public Task RegisterServiceAsync<T>(string serviceName, T serviceInstance) {
            if (string.IsNullOrEmpty(serviceName))
                throw new ArgumentException("服务名称不能为空", nameof(serviceName));

            if (serviceInstance == null)
                throw new ArgumentNullException(nameof(serviceInstance));

            var serviceInfo = new ServiceInfo {
                ServiceName = serviceName,
                ServiceInstance = serviceInstance,
                ServiceType = typeof(T),
                RegisterTime = DateTime.UtcNow,
                Methods = GetServiceMethods(typeof(T))
            };

            _services.AddOrUpdate(serviceName, serviceInfo, (key, old) => serviceInfo);
            return Task.CompletedTask;
        }

        public Task UnregisterServiceAsync(string serviceName) {
            if (string.IsNullOrEmpty(serviceName))
                throw new ArgumentException("服务名称不能为空", nameof(serviceName));

            _services.TryRemove(serviceName, out _);
            return Task.CompletedTask;
        }

        public object GetService(string serviceName) {
            return _services.TryGetValue(serviceName, out var serviceInfo)
                ? serviceInfo.ServiceInstance
                : null;
        }

        public T GetService<T>(string serviceName) {
            var service = GetService(serviceName);
            return service is T typedService ? typedService : default(T);
        }

        public bool IsServiceRegistered(string serviceName) {
            return _services.ContainsKey(serviceName);
        }

        public IReadOnlyList<string> GetRegisteredServices() {
            return _services.Keys.ToList();
        }

        public ServiceInfo GetServiceInfo(string serviceName) {
            return _services.TryGetValue(serviceName, out var serviceInfo) ? serviceInfo : null;
        }

        private Dictionary<string, MethodInfo> GetServiceMethods(Type serviceType) {
            var methods = new Dictionary<string, MethodInfo>();

            foreach (var method in serviceType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) {
                // 排除Object的基本方法
                if (method.DeclaringType == typeof(object))
                    continue;

                var key = GetMethodKey(method);
                methods[key] = method;
            }

            return methods;
        }

        private string GetMethodKey(MethodInfo method) {
            var parameters = method.GetParameters();
            var paramTypes = string.Join(",", parameters.Select(p => p.ParameterType.FullName));
            return $"{method.Name}({paramTypes})";
        }
    }

}
