from aspen_crypto.keys import (
    Ed25519PrivateKey,
    load_local_umbrella_api_key,
    persist_umbrella_api_key,
)
from console_base.utils.cli_input import readline_input
from lcconfig.configparser import ConsoleSettingsConfig
from lcrequests.umbrella import UMBRELLA_USERS
from sequential_uuids.generators import uuid_time_nextval
from uuid import UUID

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from encipher.settings import LOCAL_API_USER_CID_KEY
from encipher.utils import confirm_umbrella_user


def persist_api_user_cid(user_cid: str | UUID):
    cfg = ConsoleSettingsConfig()
    data = cfg.as_typed_dict('BoxData')
    data[LOCAL_API_USER_CID_KEY] = user_cid
    cfg.save_section('BoxData', data)


class Command(BaseCommand):
    help = "Generate Ed25519 key for local portal Umbrella API Auth"

    def add_arguments(self, parser):
        parser.add_argument(
            '--force',
            dest='force',
            action='store_true',
            help='Generate a new Umbrella API signing key whether one exists or not.',
        )

    def handle(self, *args, **options):
        force = options['force']
        User = get_user_model()

        if not force:
            try:
                load_local_umbrella_api_key()
                self.stdout.write('\nLocal API token signing key already exists\n\n')
                return
            except ValueError:
                pass

        user_cid = None
        while not user_cid:
            cid_or_subject = readline_input('User CID or Umbrella Subject: ').lower()
            if umbrella_user := UMBRELLA_USERS.get(cid_or_subject):
                user_cid = umbrella_user.cid
                confirm_umbrella_user(umbrella_user)
            else:
                try:
                    user_cid = UUID(cid_or_subject)
                    if not User.objects.filter(cid=user_cid).first():
                        self.stdout.write(f'No user found with CID: {cid_or_subject}')
                        user_cid = None
                except ValueError:
                    self.stdout.write(f"\n{cid_or_subject} not a valid CID or Umbrella Subject\n")

        private_key = Ed25519PrivateKey.generate()
        cid = uuid_time_nextval()
        persist_umbrella_api_key(key_cid=cid, private_key=private_key)
        persist_api_user_cid(user_cid)

        # Print the repr of the public key pem so it's displayed with
        # new-lines for importing via the import_umbrella_auth command.
        self.stdout.write(
            f'\nCreate a Public Key record in Aspen with these details:\n\n'
            f'Canonical ID: {str(cid)!r}\n'
            f'Public Key:\n{repr(private_key.public_key.as_pem.decode())}\n\n'
        )
