using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using Valg.EVA.Skanning.Contracts;
using Newtonsoft.Json;
using Valg.EVA.Skanning.Diagnostics;

namespace Valg.EVA.Skanning.UserInterfaceElements.Help
{
    public class HelpProvider : IHelpProvider
    {
        private readonly IExternalEndpointsConfiguration externalEndpointsConfiguration;
        private List<HelpMapping> helpMappings;

        public HelpProvider(IExternalEndpointsConfiguration externalEndpointsConfiguration)
        {
            this.externalEndpointsConfiguration = externalEndpointsConfiguration;
        }
        
        
        
        private string RemoveNoisyChars(string str)
        {
            return str.Trim().Replace(" ", string.Empty).Replace("\u00A0", string.Empty);
        }

        public Uri GetUri(string resource)
        {
            if (helpMappings == null)
            {
                helpMappings = new List<HelpMapping>();
                AttemptFillMappingList();
            }
            
            var helpMapping = helpMappings.FirstOrDefault(k =>
            {
                var resourceTrimmed = RemoveNoisyChars(resource);
                var idTrimmed = RemoveNoisyChars(k.Id);

                return string.Compare(resourceTrimmed,  idTrimmed, StringComparison.InvariantCultureIgnoreCase) == 0;
            });

            if (helpMapping != null)
            {
                return new Uri(helpMapping.Url);
            }

            return null;
        }

        private async void AttemptFillMappingList()
        {
            HttpClient httpClient = null;
            try
            {
                httpClient = new HttpClient();
                var task = httpClient.GetAsync(externalEndpointsConfiguration.HelpMappingUrl);
                task.Wait(TimeSpan.FromSeconds(5));
                if (task.IsCompleted)
                {
                    var contentBytes = await task.Result.Content.ReadAsByteArrayAsync();
                    var content = Encoding.UTF8.GetString(contentBytes);
                    
                    content = RemoveBOMIfPresent(content);

                    var asArray = JsonConvert.DeserializeObject<HelpMapping[]>(content);
                    helpMappings.AddRange(asArray);
                }
            }
            catch (Exception ex)
            {
                
                EvaSkanningEventSource.Log.ErrorWhileDownloadingHelpUriMapping(ex.ToString(), externalEndpointsConfiguration.HelpMappingUrl);
            }
            finally
            {
                if (httpClient != null)
                {
                    httpClient.Dispose();
                }
            }
        }

        private static string RemoveBOMIfPresent(string content)
        {
            if (content[0] == '\uFEFF')
            {
                content = content.Substring(1);
            }

            return content;
        }
    }
}
