/*
 * OpenAPI Petstore
 *
 * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
 *
 * The version of the OpenAPI document: 1.0.0
 * Generated by: https://github.com/openapitools/openapi-generator.git
 */

using System;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Security.Cryptography;
using Org.OpenAPITools.Client;
using Org.OpenAPITools.Api;
using Org.OpenAPITools.Extensions;
using Xunit;

namespace Org.OpenAPITools.Test.Api
{
    /// <summary>
    ///  Tests the dependency injection.
    /// </summary>
    public class DependencyInjectionTest
    {
        private readonly IHost _hostUsingConfigureWithoutAClient =
            Host.CreateDefaultBuilder([]).ConfigureApi((context, services, options) =>
            {
                ApiKeyToken apiKeyToken1 = new("<token>", ClientUtils.ApiKeyHeader.Api_key, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(apiKeyToken1);

                ApiKeyToken apiKeyToken2 = new("<token>", ClientUtils.ApiKeyHeader.Api_key_query, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(apiKeyToken2);

                BearerToken bearerToken1 = new("<token>", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(bearerToken1);

                BasicToken basicToken1 = new("<username>", "<password>", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(basicToken1);

                HttpSigningConfiguration config1 = new("<keyId>", "<keyFilePath>", null, [], HashAlgorithmName.SHA256, "<signingAlgorithm>", 0);
                HttpSignatureToken httpSignatureToken1 = new(config1, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(httpSignatureToken1);

                OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(oauthToken1);
            })
            .Build();

        private readonly IHost _hostUsingConfigureWithAClient =
            Host.CreateDefaultBuilder([]).ConfigureApi((context, services, options) =>
            {
                ApiKeyToken apiKeyToken1 = new("<token>", ClientUtils.ApiKeyHeader.Api_key, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(apiKeyToken1);

                ApiKeyToken apiKeyToken2 = new("<token>", ClientUtils.ApiKeyHeader.Api_key_query, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(apiKeyToken2);

                BearerToken bearerToken1 = new("<token>", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(bearerToken1);

                BasicToken basicToken1 = new("<username>", "<password>", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(basicToken1);

                HttpSigningConfiguration config1 = new("<keyId>", "<keyFilePath>", null, [], HashAlgorithmName.SHA256, "<signingAlgorithm>", 0);
                HttpSignatureToken httpSignatureToken1 = new(config1, timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(httpSignatureToken1);

                OAuthToken oauthToken = new("token", timeout: TimeSpan.FromSeconds(1));
                options.AddTokens(oauthToken);
                options.AddApiHttpClients(client => client.BaseAddress = new Uri(ClientUtils.BASE_ADDRESS));
            })
            .Build();

        private readonly IHost _hostUsingAddWithoutAClient =
            Host.CreateDefaultBuilder([]).ConfigureServices((host, services) =>
            {
                services.AddApi(options =>
                {
                    ApiKeyToken apiKeyToken1 = new("<token>", ClientUtils.ApiKeyHeader.Api_key, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(apiKeyToken1);

                    ApiKeyToken apiKeyToken2 = new("<token>", ClientUtils.ApiKeyHeader.Api_key_query, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(apiKeyToken2);

                    BearerToken bearerToken1 = new("<token>", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(bearerToken1);

                    BasicToken basicToken1 = new("<username>", "<password>", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(basicToken1);

                    HttpSigningConfiguration config1 = new("<keyId>", "<keyFilePath>", null, [], HashAlgorithmName.SHA256, "<signingAlgorithm>", 0);
                    HttpSignatureToken httpSignatureToken1 = new(config1, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(httpSignatureToken1);

                    OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(oauthToken1);
                });
            })
            .Build();

        private readonly IHost _hostUsingAddWithAClient =
            Host.CreateDefaultBuilder([]).ConfigureServices((host, services) =>
            {
                services.AddApi(options =>
                {
                    ApiKeyToken apiKeyToken1 = new("<token>", ClientUtils.ApiKeyHeader.Api_key, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(apiKeyToken1);

                    ApiKeyToken apiKeyToken2 = new("<token>", ClientUtils.ApiKeyHeader.Api_key_query, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(apiKeyToken2);

                    BearerToken bearerToken1 = new("<token>", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(bearerToken1);

                    BasicToken basicToken1 = new("<username>", "<password>", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(basicToken1);

                    HttpSigningConfiguration config1 = new("<keyId>", "<keyFilePath>", null, [], HashAlgorithmName.SHA256, "<signingAlgorithm>", 0);
                    HttpSignatureToken httpSignatureToken1 = new(config1, timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(httpSignatureToken1);

                    OAuthToken oauthToken1 = new("token", timeout: TimeSpan.FromSeconds(1));
                    options.AddTokens(oauthToken1);
                    options.AddApiHttpClients(client => client.BaseAddress = new Uri(ClientUtils.BASE_ADDRESS));
                });
            })
            .Build();

        /// <summary>
        /// Test dependency injection when using the configure method
        /// </summary>
        [Fact]
        public void ConfigureApiWithAClientTest()
        {
            var anotherFakeApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IAnotherFakeApi>();
            Assert.True(anotherFakeApi.HttpClient.BaseAddress != null);

            var defaultApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IDefaultApi>();
            Assert.True(defaultApi.HttpClient.BaseAddress != null);

            var fakeApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IFakeApi>();
            Assert.True(fakeApi.HttpClient.BaseAddress != null);

            var fakeClassnameTags123Api = _hostUsingConfigureWithAClient.Services.GetRequiredService<IFakeClassnameTags123Api>();
            Assert.True(fakeClassnameTags123Api.HttpClient.BaseAddress != null);

            var petApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IPetApi>();
            Assert.True(petApi.HttpClient.BaseAddress != null);

            var storeApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IStoreApi>();
            Assert.True(storeApi.HttpClient.BaseAddress != null);

            var userApi = _hostUsingConfigureWithAClient.Services.GetRequiredService<IUserApi>();
            Assert.True(userApi.HttpClient.BaseAddress != null);
        }

        /// <summary>
        /// Test dependency injection when using the configure method
        /// </summary>
        [Fact]
        public void ConfigureApiWithoutAClientTest()
        {
            var anotherFakeApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IAnotherFakeApi>();
            Assert.True(anotherFakeApi.HttpClient.BaseAddress != null);

            var defaultApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IDefaultApi>();
            Assert.True(defaultApi.HttpClient.BaseAddress != null);

            var fakeApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IFakeApi>();
            Assert.True(fakeApi.HttpClient.BaseAddress != null);

            var fakeClassnameTags123Api = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IFakeClassnameTags123Api>();
            Assert.True(fakeClassnameTags123Api.HttpClient.BaseAddress != null);

            var petApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IPetApi>();
            Assert.True(petApi.HttpClient.BaseAddress != null);

            var storeApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IStoreApi>();
            Assert.True(storeApi.HttpClient.BaseAddress != null);

            var userApi = _hostUsingConfigureWithoutAClient.Services.GetRequiredService<IUserApi>();
            Assert.True(userApi.HttpClient.BaseAddress != null);
        }

        /// <summary>
        /// Test dependency injection when using the add method
        /// </summary>
        [Fact]
        public void AddApiWithAClientTest()
        {
            var anotherFakeApi = _hostUsingAddWithAClient.Services.GetRequiredService<IAnotherFakeApi>();
            Assert.True(anotherFakeApi.HttpClient.BaseAddress != null);
            
            var defaultApi = _hostUsingAddWithAClient.Services.GetRequiredService<IDefaultApi>();
            Assert.True(defaultApi.HttpClient.BaseAddress != null);
            
            var fakeApi = _hostUsingAddWithAClient.Services.GetRequiredService<IFakeApi>();
            Assert.True(fakeApi.HttpClient.BaseAddress != null);
            
            var fakeClassnameTags123Api = _hostUsingAddWithAClient.Services.GetRequiredService<IFakeClassnameTags123Api>();
            Assert.True(fakeClassnameTags123Api.HttpClient.BaseAddress != null);
            
            var petApi = _hostUsingAddWithAClient.Services.GetRequiredService<IPetApi>();
            Assert.True(petApi.HttpClient.BaseAddress != null);
            
            var storeApi = _hostUsingAddWithAClient.Services.GetRequiredService<IStoreApi>();
            Assert.True(storeApi.HttpClient.BaseAddress != null);
            
            var userApi = _hostUsingAddWithAClient.Services.GetRequiredService<IUserApi>();
            Assert.True(userApi.HttpClient.BaseAddress != null);
        }

        /// <summary>
        /// Test dependency injection when using the add method
        /// </summary>
        [Fact]
        public void AddApiWithoutAClientTest()
        {
            var anotherFakeApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IAnotherFakeApi>();
            Assert.True(anotherFakeApi.HttpClient.BaseAddress != null);

            var defaultApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IDefaultApi>();
            Assert.True(defaultApi.HttpClient.BaseAddress != null);

            var fakeApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IFakeApi>();
            Assert.True(fakeApi.HttpClient.BaseAddress != null);

            var fakeClassnameTags123Api = _hostUsingAddWithoutAClient.Services.GetRequiredService<IFakeClassnameTags123Api>();
            Assert.True(fakeClassnameTags123Api.HttpClient.BaseAddress != null);

            var petApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IPetApi>();
            Assert.True(petApi.HttpClient.BaseAddress != null);

            var storeApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IStoreApi>();
            Assert.True(storeApi.HttpClient.BaseAddress != null);

            var userApi = _hostUsingAddWithoutAClient.Services.GetRequiredService<IUserApi>();
            Assert.True(userApi.HttpClient.BaseAddress != null);
        }
    }
}
