using System.Diagnostics;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

//集成 asp.net core 引用 TestHost(3.0+)
using Microsoft.AspNetCore.TestHost;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using Xunit;
using Xunit.DependencyInjection;

//如果使用最小API,则引用
using Xunit.DependencyInjection.AspNetCoreTesting;

using Xunit.DependencyInjection.Logging;

namespace HttpClientStudy.UnitTest
{
    /// <summary>
    /// 依赖注入框架:Xunit.DependencyInjection, 必备设置类
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 创建主机:可选,一般不用
        /// </summary>
        /// <returns></returns>
        public IHostBuilder CreateHostBuilder()
        {
            return Host.CreateDefaultBuilder();
        }

        /// <summary>
        /// 配置主机:可选(集成Asp.Net Core时,配置主机)
        /// </summary>
        /// <param name="hostBuilder"></param>
        public void ConfigureHost(IHostBuilder hostBuilder)
        {
            //确保启动 webapi 项目
            StartWebApiProject();

            hostBuilder
                //主机配置
                .ConfigureHostConfiguration(builder =>
                {

                })
                //应用配置
                .ConfigureAppConfiguration((context, builder) =>
                {

                })
                //配置Web主机
                .ConfigureWebHost(webHostBuilder =>
                {
                    webHostBuilder
                        //测试主机,集成测试使用
                        .UseTestServer(options => 
                        { 
                            options.PreserveExecutionContext = true; 
                        })
                        .ConfigureTestServices(a => 
                        { 
                        
                        })
                        .UseStartup<WebApiStartup>();

                    //配置默认配置项
                    //webHostBuilder.ConfigureAppConfiguration((context, configBuilder) =>
                    //{
                    //    configBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
                    //    configBuilder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
                    //});

                    //webHostBuilder.ConfigureServices(services => 
                    //{
                    //    services.AddHealthChecks(); 
                    //});
                });
        }

        /// <summary>
        /// 注册服务:必须
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
        {
            Debugger.Log(1, "DI", "ConfigureServices");
        }

        /// <summary>
        /// 启动webapi项目
        /// (出现webapi项目启动命令行窗口)
        /// </summary>
        private void StartWebApiProject()
        {
            string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;

            //webapi项目不在运行状态则启动webapi项目
            if (webAppIsRunningByMutex() == false)
            {
                //VS项目根目录
                string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;

                //webapi项目根项目
                string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);

                //启动命令信息
                var prossInfo = new ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
                {
                    UseShellExecute = true,
                    CreateNoWindow = false,
                    RedirectStandardOutput = false
                };

                //启动
                Process.Start(prossInfo);
            }

            //由进程名判断
            //bool webAppIsRunningByProcessName()
            //{
            //    return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
            //}

            //由互斥锁判断
            bool webAppIsRunningByMutex()
            {
                bool createdResult = true;

                //创建互斥锁
                using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
                {
                    if (createdResult)
                    { 
                        mutex.ReleaseMutex();
                    }
                }

                //互斥锁是否创建成功
                return !createdResult;
            }

        }

        private class WebApiStartup
        {
            public void ConfigureServices(IServiceCollection services) 
            {
                services.AddLogging(lb => lb.AddXunitOutput()); 
            }

            public void Configure(IApplicationBuilder app)
            {
                app.Run(static context => context.Response.WriteAsync("xxxxxx"));
            }
        }
    }
}