import argparse
import os
import uuid

import boto3
import psycopg
from src.logger import logger
from src.usecases.contract_provider_usecase import ContractProviderUseCase

USER_POOL_ID = os.getenv("USER_POOL_ID")
POSTGRES_HOST = os.getenv("POSTGRES_HOST")
POSTGRES_PORT = os.getenv("POSTGRES_PORT")
POSTGRES_USER = os.getenv("POSTGRES_USER")
POSTGRES_PASSWORD = os.getenv("POSTGRES_PASSWORD")
POSTGRES_DB = os.getenv("POSTGRES_DB")


def main(name: str) -> None:
    logger.info(f"NAME: {name}")

    contract_provider_id = uuid.uuid4()
    logger.info(f"CONTRACT_PROVIDER_ID: {contract_provider_id}")
    application_client_id = __create_application_client(contract_provider_id=contract_provider_id)
    logger.info(f"APPLICATION_CLIENT_ID: {application_client_id}")

    with psycopg.connect(
        host=os.environ["POSTGRES_HOST"],
        port=os.environ["POSTGRES_PORT"],
        user=os.environ["POSTGRES_USER"],
        password=os.environ["POSTGRES_PASSWORD"],
        dbname=os.environ["POSTGRES_DB"],
        autocommit=True,
    ) as connection:
        usecase = ContractProviderUseCase.create(
            connection=connection,
        )

        usecase.add(
            contract_provider_id=contract_provider_id,
            name=name,
            application_client_id=application_client_id,
        )


def __create_application_client(contract_provider_id: uuid.UUID) -> str:
    client = boto3.client("cognito-idp")
    response = client.create_user_pool_client(
        UserPoolId=USER_POOL_ID,
        ClientName=str(contract_provider_id),
        GenerateSecret=True,
        AccessTokenValidity=24,
        TokenValidityUnits={
            "AccessToken": "hours",
        },
        EnableTokenRevocation=True,
        AllowedOAuthFlowsUserPoolClient=True,
        AllowedOAuthFlows=[
            "client_credentials",
        ],
        AllowedOAuthScopes=[
            "m2m/contract",
        ],
        ExplicitAuthFlows=[
            "CUSTOM_AUTH_FLOW_ONLY",
        ],
    )
    return response["UserPoolClient"]["ClientId"]


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Contract Provider Creator Script")
    parser.add_argument(
        "--name",
        type=str,
        required=True,
    )

    args = parser.parse_args()
    main(
        name=args.name,
    )
