using Amazon.S3;
using Amazon.S3.Model;
using Microsoft.Extensions.Options;
using OnlineAssessment.Models;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Specialized;

namespace OnlineAssessment.Helpers
{
    public interface IAWSS3BucketHelper
    {
        Task<string> UploadFile(System.IO.Stream inputStream, string fileName);
        Task<bool> UploadFileWithMeta(System.IO.Stream inputStream, string fileName, string meta);
        Task<ListVersionsResponse> FilesList();
        Task<Stream> GetFile(string key);
        Task<GetObjectMetadataResponse> MetaDetail(string fileName);
        Task<bool> DeleteFile(string key);
    }
    public class AWSS3BucketHelper : IAWSS3BucketHelper
    {
        private readonly IAmazonS3 _amazonS3;
        private readonly ServiceConfiguration _settings;
        public AWSS3BucketHelper(IAmazonS3 s3Client, IOptions<ServiceConfiguration> settings)
        {
            this._amazonS3 = s3Client;
            this._settings = settings.Value;
        }
        public async Task<string> UploadFile(System.IO.Stream inputStream, string fileName)
        {
            try
            {
                PutObjectRequest request = new PutObjectRequest()
                {
                    InputStream = inputStream,
                    BucketName = _settings.AWSS3.BucketName,
                    Key = fileName
                };
                PutObjectResponse response = await _amazonS3.PutObjectAsync(request);
                if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
                    return $"https://{_settings.AWSS3.BucketName}.s3.{_settings.AWSS3.Region}.amazonaws.com/{fileName}";
                else
                    return null;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public async Task<bool> UploadFileWithMeta(System.IO.Stream inputStream, string fileName, string meta)
        {
            try
            {
                
                PutObjectRequest request = new PutObjectRequest()
                {
                    InputStream = inputStream,
                    BucketName = _settings.AWSS3.BucketName,
                    Key = fileName
                };
                //request.Metadata.Add("meta-title", "someTitle");

                PutObjectResponse response = await _amazonS3.PutObjectAsync(request);
                if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        public async Task<ListVersionsResponse> FilesList()
        {
            return await _amazonS3.ListVersionsAsync(_settings.AWSS3.BucketName);
        }

        public async Task<GetObjectMetadataResponse> MetaDetail(string fileName)
        {
            GetObjectMetadataRequest request = new GetObjectMetadataRequest()
            {
                BucketName = _settings.AWSS3.BucketName,
                Key = fileName
            };
            
            return await _amazonS3.GetObjectMetadataAsync(request);
            
        }

        

        public async Task<Stream> GetFile(string key)
        {
            string file = key + ".png";
            GetObjectResponse response = await _amazonS3.GetObjectAsync(_settings.AWSS3.BucketName, file);
            if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
                return response.ResponseStream;
            else
                return null;
        }

        public async Task<bool> DeleteFile(string key)
        {
            try
            {
                DeleteObjectResponse response = await _amazonS3.DeleteObjectAsync(_settings.AWSS3.BucketName, key);
                if (response.HttpStatusCode == System.Net.HttpStatusCode.NoContent)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }


        }
    }
}