from subprocess import run
from os.path import join, isfile, isdir
from datetime import datetime
from shutil import copyfile
from os import makedirs, listdir, unlink


TMP_DIR = '/srv/tls/tmp'
LE_DIR = '/srv/tls/x509/letsencrypt'


def letsencrypt_certif(cn: str,
                       authority_cn: str,
                       authority_name: str,
                       type_: str,
                       config: str,
                       ) -> None:
    if type_ != 'server':
        raise Exception("Let's Encrypt is only available for server certificate")
    date = datetime.now()
    today = str(date.date())
    week_number = date.isocalendar().week
    certificate_name = f'certificate_{week_number}.crt'
    rootdir = join(LE_DIR, f'{authority_name}+{authority_cn}')
    certdir = join(rootdir, 'certificats', cn, 'server')
    chaindir = join(rootdir, 'certificats', cn, 'ca')
    key_name = join(certdir, 'private.key')
    cert_name = join(certdir, certificate_name)
    email_address = config['email']
    if not isfile(cert_name):
        cli_args = ['certbot',
                    'certonly',
# WEB
                    '--standalone',
# DNS
#                    f'--dns-{plugin_name}',
#                    f'--dns-{plugin_name}-credentials',
#                    credential_filename,
#                    '--dns-ovh-propagation-seconds',
#                    '360',
                    '-d',
                    cn,
                    '--http-01-port',
                    '8080',
                    '--quiet',
                    '--config-dir', 
                    f'{TMP_DIR}/{cn}/config',
                    '--work-dir',
                    f'{TMP_DIR}/{cn}/work',
                    '--logs-dir',
                    f'{TMP_DIR}/{cn}/logs',
#                    '--test-cert',
                    '--agree-tos',
                    '-m',
                    email_address,
                    ]
        ret = run(cli_args, capture_output=True)
        if ret.returncode:
            raise Exception(f"error with Let's encrypt: {ret.stderr}")
        
        for dirname in (chaindir, certdir):
            if not isdir(dirname):
                makedirs(dirname)
        copyfile(join(TMP_DIR, cn, 'config/live', cn, 'privkey.pem'),
                 key_name,
                 )
        copyfile(join(TMP_DIR, cn, 'config/live', cn, 'fullchain.pem'),
                 cert_name,
                 )
        for dirname in (chaindir, certdir):
            for filename in listdir(dirname):
                if not filename.endswith('.crt') or filename == certificate_name:
                    continue
                unlink(join(dirname, filename))
    return None, cert_name, key_name