using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Amazon.S3;

//for ssl certs
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;

namespace rockfishCore.Util
{
    public static class OpsDiagnostics
    {
        private const string S3_SECRET_KEY = "iNwbHr+sK+9is2wmRjIax+rdyEjLNvWKJBYr7w4txkY";
        private const string S3_ACCESS_KEY = "CMPAFDNX53OWPC55HBJ4";
        private const string S3_HOST_ENDPOINT = "https://nyc3.digitaloceanspaces.com";
        private const string S3_BUCKET_NAME = "gztw1";

        private static readonly HttpClient _httpClient;


        static OpsDiagnostics()
        {
            _httpClient = new HttpClient();
        }

        public static bool CheckWebsite(string url, string mustContain)
        {
            bool Result = false;
            var Response = _httpClient.GetAsync(url).Result;
            if (Response.IsSuccessStatusCode)
            {
                var PageText = Response.Content.ReadAsStringAsync().Result;
                if (PageText.Contains(mustContain))
                {
                    Result = true;
                }
            }
            return Result;
        }


        /// <summary>
        /// check if an ssl cert is within 30 days of expiry
        /// (30 days is the minimum threshold for LetsEncrypt to allow re-up)
        /// </summary>
        /// <param name="url"></param>
        /// <returns>null if more than 30 days before expiry or the expiry date for display</returns>
        public static DateTime? SSLCertExpiryDate(string url)
        {
            var expires = GetServerCertificateExpiryAsync(url).Result;
            //In 30 days will we be past the expiry date?
            var deadline = DateTime.Now.AddDays(30);
            if (expires < deadline)
            {
                return expires;
            }

            return null;
        }



        static async Task<DateTime> GetServerCertificateExpiryAsync(string url)
        {
            DateTime ret = DateTime.MinValue;
            var httpClientHandler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (_, cert, __, ___) =>
                {
                    ret = cert.NotAfter;
                    return true;
                }
            };

            using (var httpClient = new HttpClient(httpClientHandler))
            {
                await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));
                //httpClient.Dispose();
            }
            return ret;
        }






        public static List<string> GetFileListFromSpacesBackupStorage()
        {
            AmazonS3Config ClientConfig = new AmazonS3Config();
            ClientConfig.ServiceURL = S3_HOST_ENDPOINT;
            IAmazonS3 s3Client = new AmazonS3Client(S3_ACCESS_KEY, S3_SECRET_KEY, ClientConfig);
            var ObjectList = s3Client.ListObjectsAsync(S3_BUCKET_NAME).Result;
            var FileList = ObjectList.S3Objects.Select(c => c.Key).ToList();
            return FileList;
        }

        public static bool VerifyBackups()
        {
            string[] CriticalDailyBackupFilePrefixes = { "ayanova21-pecklist-db-backup-", "ayanova21-rockfish-db-backup-", "mail21-svn-backup-", "forum21-backup-" };
            string[] Level2ManualBackupFilePrefixes = { "ayanova21-website-backup-" };
            var SpacesFileNames = GetFileListFromSpacesBackupStorage();

            //Daily critical files
            //get yesterday's date in the same format as the backup creates
            var ExpectedBackupDateString = DateTime.Today.AddDays(-1).ToString("yyMMdd");
            int FoundCriticalMatches = 0;
            foreach (string ExpectedFileName in CriticalDailyBackupFilePrefixes)
            {
                foreach (string FileName in SpacesFileNames)
                {
                    if (FileName.StartsWith(ExpectedFileName + ExpectedBackupDateString))
                    {
                        FoundCriticalMatches++;
                        break;
                    }
                }
            }

            //Manual backups are random in quantity so just confirm there is at least one
            //we dont' care about date for these ones, just presence of at least one
            int FoundLevel2Matches = 0;
            foreach (string ExpectedFileName in Level2ManualBackupFilePrefixes)
                foreach (string FileName in SpacesFileNames)
                    if (FileName.StartsWith(ExpectedFileName))
                    {
                        FoundLevel2Matches++;
                        break;
                    }

            //At least one of each separate manual backup file          
            return (FoundCriticalMatches == CriticalDailyBackupFilePrefixes.Length && FoundLevel2Matches == Level2ManualBackupFilePrefixes.Length);
        }



    }//eoc

}//eons