using eSuite.WorkBench.Services.ContainerRegistryResponses;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace eSuite.WorkBench.Services
{
    public class ContainerRegistryClient : IContainerRegistryClient
    {
        //Here's the reference for the docker registry api https://docs.docker.com/registry/spec/api/
        //Here's the reference for the azure container registry api https://learn.microsoft.com/en-us/rest/api/containerregistry/
        private string Token { get; set; }

        private readonly string _baseUrl = "https://esuite.azurecr.io";
        private readonly HttpClient _client = new();

        public ContainerRegistryClient()
        {
            Token = GetBearerToken();
            _client.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("Bearer", Token);
        }

        private string GetBearerToken()
        {
            var username = ConfigurationManager.AppSettings["AzureContainerRegistryUserName"];
            var password = ConfigurationManager.AppSettings["AzureContainerRegistryPassword"];
            var basicAuthentication = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(username + ":" + password));

            var client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basicAuthentication);

            var response = client.GetAsync(new Uri($"{_baseUrl}/oauth2/token?service=esuite.azurecr.io&scope=repository:*:*")).GetAwaiter().GetResult();
            response.EnsureSuccessStatusCode();
            var tokenJson = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

            dynamic json = JsonConvert.DeserializeObject(tokenJson);
            return json!.access_token.ToString();
        }

        public async Task<IEnumerable<string>> GetTagsListAsync(string name)
        {
            //var message = new HttpRequestMessage
            //{
            //    Method = HttpMethod.Get,
            //    RequestUri = new Uri($"{_baseUrl}/{name}/tags/list"),
            //    Headers =
            //    {
            //        {HttpRequestHeader.Authorization.ToString(), $"Basic {Token}" }
            //    }
            //};
            //var rawResult = (await _client.SendAsync(message)).EnsureSuccessStatusCode();
            try
            {
                var rawResult = (await _client.GetAsync(new Uri($"{_baseUrl}/v2/{name}/tags/list")));
                rawResult.EnsureSuccessStatusCode();
                return JsonConvert.DeserializeObject<TagsListResponse>(await rawResult.Content.ReadAsStringAsync())
                    .Tags;
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        public async Task DeleteImageAsync(string name, string reference)
        {
        //var message = new HttpRequestMessage
        //{
        //    Method = HttpMethod.Delete,
        //    RequestUri = ,
        //    Headers =
        //    {
        //        {HttpRequestHeader.Authorization.ToString(), $"Basic {Token}" }
        //    }
        //};
            var rawResult = (await _client.DeleteAsync(new Uri($"{_baseUrl}/acr/v1/{name}/_tags/{reference}"))).EnsureSuccessStatusCode();
            //return JsonConvert.DeserializeObject<TagsListResponse>(await rawResult.Content.ReadAsStringAsync()).Tags;
        }

        public IEnumerable<string> GetTagsList(string name)
        {
            var message = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri($"{_baseUrl}/v2/{name}/tags/list"),
                Headers =
                {
                    {HttpRequestHeader.Authorization.ToString(), $"Basic {Token}" }
                }
            };
            var rawResult = (_client.Send(message)).EnsureSuccessStatusCode();
            var resultString = rawResult.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<TagsListResponse>(resultString.Result).Tags;
        }
    }
}
