using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using ThoughtWorks.CruiseControl.Core.Util;
using Amazon.S3;
using System.IO;
using Microsoft.Extensions.Logging;
using Amazon.S3.Transfer;
using System.Windows.Forms;
using System.Net;

namespace CCNetLogReader
{
    public class s3Config
    {
        public string accessKey = "AKIA4SZHOEQBTOZHRNVC";
        public string secretKey = "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";
        public string region = "us-east-2"; // Amazon.RegionEndpoint.USEast2;
        public string bucket = "";
        public string cloudfrontDomainName = "";
    }

    public class s3Client
    {
        IAmazonS3 _s3;
        s3Config _config = new s3Config();
        //ILogger _log;
        public s3Client(s3Config config)
        {
            //var logFactory = LoggerFactory.Create(b => b.AddSimpleConsole(
            //    s =>
            //    {
            //        s.SingleLine = true;
            //        s.IncludeScopes = true;
            //        s.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";
            //    }
            //));

            //_log = logFactory.CreateLogger<s3Client>();

            //_log.LogInformation("Constructing ZendeskClient.");
            if (null != config)
                _config = config;

            _s3 = new AmazonS3Client(
                _config.accessKey,
                _config.secretKey,
                new AmazonS3Config()
                {
                    RegionEndpoint = Amazon.RegionEndpoint.GetBySystemName(_config.region)
                }
            );

            //_log.LogInformation($"Connected to s3 in {_config.region}");
            var l = _s3.ListBuckets();
            if (!l.Buckets.Select(s => s.BucketName).Contains(_config.bucket))
                //_log.LogInformation($"Bucket {_config.bucket} found.");
            //else
            {
                //_log.LogInformation($"Bucket {_config.bucket} NOT found.");
                throw new Exception("Not Connected to AWS S3!");
            }
        }

        public void uploadAndClearFolder(string s3folder, List<string> localFileNames)
        {
            //_log.LogInformation("Insuring s3 folder structure.");
            var opts = new Amazon.S3.Model.PutObjectRequest()
            {
                BucketName = _config.bucket,
                Key = s3folder,
            };
            var create = _s3.PutObject(opts);

            //_log.LogInformation("Finding existing files.");
            var currentContents = _s3.ListObjectsV2(new Amazon.S3.Model.ListObjectsV2Request()
            {
                BucketName = _config.bucket,
                Prefix = s3folder,
            });
            //_log.LogInformation($"Files found: {string.Join(",", currentContents.S3Objects.Select(s => s.Key))}");

            //if (currentContents.S3Objects.Select(s => s.Key).Contains(s3folder + s3keys))
            //{
            //    //_log.LogInformation($"File {s3folder + s3key} exists. Skipping.");
            //    return;
            //}

            //_log.LogInformation($"Uploading {localFileName}");
            foreach (var f in localFileNames)
            {
                var uploadRequest = new TransferUtilityUploadRequest
                {
                    BucketName = _config.bucket,
                    FilePath = f,
                    Key = s3folder + "/" + Path.GetFileName(f),
                    CannedACL = S3CannedACL.PublicRead,
                };

                //uploadRequest.UploadProgressEvent += 
                //    new EventHandler<UploadProgressArgs>((object sender, UploadProgressArgs e) => 
                //    { 

                //    });

                var fileTransferUtility = new TransferUtility(_s3);
                fileTransferUtility.Upload(uploadRequest);

            }
            //_log.LogInformation($"Upload {s3key} complete.");

            //_log.LogInformation("Deleting pre-existing files.");
            foreach (var o in currentContents.S3Objects)
            {
                if (localFileNames.Select(lfn => Path.GetFileName(lfn)).Contains(o.Key)) continue;
                if (o.Key.EndsWith("/")) continue;
                if (localFileNames.Contains(o.Key)) continue;

                _s3.DeleteObject(_config.bucket, o.Key);
                //_log.LogInformation($"{o.Key} deleted.");
            }
        }
    }
}
