using System;
using System.Reflection;

namespace JsonRpc.AspNetCore.Builder
{
    public class ConstructorBuilder : IBuilder
    {
        private ConstructorInfo constructorInfo = null;
        private IServiceProvider serviceProvider = null;

        public ConstructorBuilder(Type type, IServiceProvider serviceProvider)
        {
            if(type == null || serviceProvider == null)
            {
                throw new ArgumentNullException("type or serviceProvider");
            }

            var constructors = type.GetConstructors();
            foreach(var constructor in constructors)
            {
                var parameters = constructor.GetParameters();
                bool fit = true;
                foreach(var param in parameters)
                {
                    var service = serviceProvider.GetService(param.ParameterType);
                    if(service == null || service.GetType() != param.ParameterType)
                    {
                        fit = false;
                        break;
                    }
                }
                if(fit)
                {
                    this.constructorInfo = constructor;
                    break;
                }
            }

            if(this.constructorInfo == null)
            {
                throw new Exception($"{type.FullName} cannot be inited with services in container");
            }
        }

        public object Build()
        {
            var parameters = this.constructorInfo.GetParameters();
            var services = new object[parameters.Length];
            for(int i = 0; i < parameters.Length; i++)
            {
                var param = parameters[i];
                var service = this.serviceProvider.GetService(param.ParameterType);
                if(service != null && service.GetType() == param.ParameterType)
                {
                    services[i] = service;
                }
            }
            return this.constructorInfo.Invoke(services);
        }
    }
}