using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Valg.EVA.Skanning.ServicesModel.Internal.SystemSettings;

namespace Valg.EVA.Skanning.Scan.Startup.StateReporting
{
    public class HttpsReportSink : HttpReportSink
    {
        private readonly string _productionCertificateIssuerParams;
        private readonly string _trainingCertificateIssuerParams;


        public HttpsReportSink(ISystemSettingsProvider systemSettings, string endpointAddress) :base(endpointAddress)
        {
            _productionCertificateIssuerParams = systemSettings.GetProductionCertificateIssuerParams();
            _trainingCertificateIssuerParams = systemSettings.GetTrainingCertificateIssuerParams();
        }
        protected override async Task SendAsync(StateReport report)
        {
            var values = new Dictionary<string, string>
            {
                { "report", JsonConvert.SerializeObject(report) }
            };
            var clientCert = FindClientCertificate();
            var requestHandler = new WebRequestHandler();
            requestHandler.ClientCertificates.Add(clientCert);
            var client = new HttpClient(requestHandler);
            var content = new FormUrlEncodedContent(values);
            var response = client.PostAsync(EndpointAddress, content);
            await response.Result.Content.ReadAsStringAsync();

        }

        private X509Certificate2 FindClientCertificate()
        {
            var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            try
            {
                store.Open(OpenFlags.ReadOnly);

                var validCertificates = store.Certificates.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
                var findType = X509FindType.FindByIssuerDistinguishedName;
                var matchingCertificate = validCertificates.Find(findType, _productionCertificateIssuerParams, false);

                if (matchingCertificate.Count == 0)
                {
                    matchingCertificate = validCertificates.Find(findType, _trainingCertificateIssuerParams, false);
                }

                return matchingCertificate.Count > 0 ? matchingCertificate[0] : null;
            }
            finally
            {
                store.Close();
            }
        }

    }
}

