using System.Security.Cryptography;
using Flurl;
using Flurl.Http;
using InnovEnergy.Lib.Utils;
using static System.Text.Encoding;
using Convert = System.Convert;

namespace InnovEnergy.S3.Drivers;

public record S3Config
{
    public String Bucket      { get; init; } = "";
    public String Region      { get; init; } = "";
    public String Provider    { get; init; } = "";
    public String Key         { get; init; } = "";
    public String Secret      { get; init; } = "";
    public String ContentType { get; init; } = "";

    public String Host =>  $"{Bucket}.{Region}.{Provider}";
    public String Url  =>  $"https://{Host}";

    public IFlurlRequest CreatePutRequest(String s3Path) => CreateRequest("PUT", s3Path);
    public IFlurlRequest CreateGetRequest(String s3Path) => CreateRequest("GET", s3Path);

    private IFlurlRequest CreateRequest(String method, String s3Path)
    {
        var date = DateTime.UtcNow.ToString("r");
        var auth = CreateAuthorization(method, s3Path, date);

        return Url
            .AppendPathSegment(s3Path)
            .WithHeader("Host", Host)
            .WithHeader("Date", date)
            .WithHeader("Authorization", auth)
            .AllowAnyHttpStatus();
    }

    private String CreateAuthorization(String method,
        String s3Path,
        String date)
    {
        return CreateAuthorization
        (
            method     : method,
            bucket     : Bucket,
            s3Path     : s3Path,
            date       : date,
            s3Key      : Key,
            s3Secret   : Secret,
            contentType: ContentType
        );
    }



    private static String CreateAuthorization(String method,
        String bucket,
        String s3Path,
        String date,
        String s3Key,
        String s3Secret,
        String contentType = "",
        String md5Hash = "")
    {
        // StringToSign = HTTP-Verb + "\n" +
        //                Content-MD5 + "\n" +
        //                Content-Type + "\n" +
        //                Date + "\n" +
        //                CanonicalizedAmzHeaders +
        //                CanonicalizedResource;

        var payload = $"{method}\n{md5Hash}\n{contentType}\n{date}\n/{bucket.Trim('/')}/{s3Path.Trim('/')}";
        using var hmacSha1 = new HMACSHA1(UTF8.GetBytes(s3Secret));

        var signature = UTF8
            .GetBytes(payload)
            .Apply(hmacSha1.ComputeHash)
            .Apply(Convert.ToBase64String);

        return $"AWS {s3Key}:{signature}";
    }

}