﻿using System;
using System.Data;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading.Tasks;
using HtmlAgilityPack;

namespace WarframeDropRatesDataParser
{
    /// <summary>
    /// </summary>
    public class DropRatesDataParser
    {
        /// <summary>
        /// </summary>
        public DropRatesDataParser() : this(new Uri(
            "https://n8k6e2y6.ssl.hwcdn.net/repos/hnfvc0o3jnfvc873njb03enrf56.html", UriKind.Absolute))
        {
        }

        /// <summary>
        /// </summary>
        /// <param name="dropRatesDataUri"></param>
        public DropRatesDataParser(Uri dropRatesDataUri)
        {
            DropRatesDataUri = dropRatesDataUri;
        }

        /// <summary>
        /// </summary>
        public Uri DropRatesDataUri { get; set; }

        /// <summary>
        /// </summary>
        /// <returns></returns>
        public async Task<HttpResponseMessage> GetDropRatesHttpResponseAsync()
        {
            using (var handler = new HttpClientHandler { AllowAutoRedirect = false, UseCookies = false })
            using (var client = new HttpClient(handler))
            {
                client.DefaultRequestHeaders.Connection.Add(@"Keep-Alive");
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(@"text/html"));
                client.DefaultRequestHeaders.AcceptLanguage.Add(StringWithQualityHeaderValue.Parse(@"en-US"));
                client.DefaultRequestHeaders.UserAgent.Add(
                    ProductInfoHeaderValue.Parse(Assembly.GetExecutingAssembly().GetName().Name));

                var response = await client.GetAsync(DropRatesDataUri, HttpCompletionOption.ResponseHeadersRead);
                response.EnsureSuccessStatusCode();

                return response;
            }
        }

        /// <summary>
        /// </summary>
        /// <param name="dropRatesHttpResponse"></param>
        /// <returns></returns>
        public async Task<DropRatesRawData> ParseDropRatesToRawDataAsync(HttpResponseMessage dropRatesHttpResponse)
        {
            string htmlContent = await dropRatesHttpResponse.Content.ReadAsStringAsync();
            return await ParseDropRatesToRawDataAsync(htmlContent);
        }

        /// <summary>
        /// </summary>
        /// <param name="dropRatesHtmlContent"></param>
        /// <returns></returns>
        public async Task<DropRatesRawData> ParseDropRatesToRawDataAsync(string dropRatesHtmlContent)
        {
            return await Task.Run(() =>
            {
                var htmlData = new HtmlDocument();
                htmlData.LoadHtml(dropRatesHtmlContent);

                var builder = new RawDataBuilder();
                var director = new DataFormatBuildDirector(builder, htmlData);
                director.BuildData();

                return builder.GetDropRatesRawData();
            });
        }

        /// <summary>
        /// </summary>
        /// <param name="dropRatesHttpResponse"></param>
        /// <returns></returns>
        public async Task<DataSet> ParseDropRatesToDataSetAsync(HttpResponseMessage dropRatesHttpResponse)
        {
            string htmlContent = await dropRatesHttpResponse.Content.ReadAsStringAsync();
            return await ParseDropRatesToDataSetAsync(htmlContent);
        }

        /// <summary>
        /// </summary>
        /// <param name="dropRatesHtmlContent"></param>
        /// <returns></returns>
        public async Task<DataSet> ParseDropRatesToDataSetAsync(string dropRatesHtmlContent)
        {
            return await Task.Run(() =>
            {
                var htmlData = new HtmlDocument();
                htmlData.LoadHtml(dropRatesHtmlContent);

                var builder = new DataSetBuilder();
                var director = new DataFormatBuildDirector(builder, htmlData);
                director.BuildData();

                return builder.GetDataSet();
            });
        }
    }
}