using System.Collections.Concurrent;
using System.Net;
using Amazon.CognitoIdentityProvider;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.Runtime;
using InnovEnergy.Lib.S3Utils.DataTypes;
using InnovEnergy.Lib.Utils;
using S3Region = InnovEnergy.Lib.S3Utils.DataTypes.S3Region;

namespace InnovEnergy.Lib.S3Utils;

public static class Iam
{
    
    // TODO

    private static readonly ConcurrentDictionary<S3Region, AmazonIdentityManagementServiceClient> AimClientCache = new();
    
    public static AmazonIdentityManagementServiceClient GetIamClient(this S3Url    url   ) => url.Bucket.GetIamClient();
    public static AmazonIdentityManagementServiceClient GetIamClient(this S3Bucket bucket) => bucket.Region.GetIamClient();
    public static AmazonIdentityManagementServiceClient GetIamClient(this S3Region region)
    {
        return AimClientCache.GetOrAdd(region, CreateIamClient); // Memoize
    }
    
    private static AmazonIdentityManagementServiceClient CreateIamClient(S3Region region) => new
    (
        credentials: new BasicAWSCredentials(region.Credentials.Key, region.Credentials.Secret),
        clientConfig: new() { ServiceURL = region.Name.EnsureStartsWith("https://") }
    );
    
    public static async Task<Role> CreateRoleAsync(AmazonIdentityManagementServiceClient iamService,String userName)
    {
        var response = await iamService.CreateRoleAsync(new CreateRoleRequest() { RoleName = userName });
        return response.Role;
    }
    
    public static async Task<Boolean> PutRolePolicyAsync(AmazonIdentityManagementServiceClient iamService, String userName, String policyName, String policyDocument)
    {
        var request = new PutRolePolicyRequest()
        {
            RoleName = userName,
            PolicyName = policyName,
            PolicyDocument = policyDocument
        };

        var response = await iamService.PutRolePolicyAsync(request);
        return response.HttpStatusCode == System.Net.HttpStatusCode.OK;
    }
    
    public static async Task<AccessKey> CreateAccessKeyAsync(AmazonIdentityManagementServiceClient iamService, String userName)
    {
        // iamService.Role
        var response = await iamService.CreateAccessKeyAsync(new CreateAccessKeyRequest
        {
             UserName= userName,
        });

        return response.AccessKey;

    }

    public static async Task<Boolean> RoleExists(AmazonIdentityManagementServiceClient iamService, String roleName)
    {
        var response = await iamService.GetRoleAsync(new GetRoleRequest{RoleName = roleName});
        return response.HttpStatusCode == HttpStatusCode.OK;
    }

    public static async Task<Boolean> RevokeAccessKey(AmazonIdentityManagementServiceClient iamService, String userName)
    {
        var response = await iamService.DeleteAccessKeyAsync(new DeleteAccessKeyRequest{ AccessKeyId = userName });
        return response.HttpStatusCode == HttpStatusCode.OK;
    }
}