"""Root-only EC2 deployment. Runtime role cannot read the RDS owner secret."""
import json
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import urllib.request


def run(args, **kwargs):
    return subprocess.run(args, check=True, **kwargs)


def main():
    if os.geteuid() != 0:
        raise SystemExit('Run through the approved root maintenance session')
    config = json.loads(Path('/opt/three-tier/config.json').read_text())
    aws = ['aws', '--region', config['region']]
    raw = run(aws + ['secretsmanager', 'get-secret-value', '--secret-id', config['secret'],
                    '--query', 'SecretString', '--output', 'text'], capture_output=True).stdout
    secret = json.loads(raw)
    root = Path('/run/three-tier-secrets')
    root.mkdir(mode=0o700, exist_ok=True)
    os.chown(root, 10001, 10001)
    os.chmod(root, 0o700)
    for name, body in [('api.dsn', secret['api_dsn']), ('worker.dsn', secret['worker_dsn']),
                       ('auth.json', json.dumps(secret['auth']))]:
        p = root / name
        fd = os.open(p, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o400)
        with os.fdopen(fd, 'w') as f:
            f.write(body)
        os.chown(p, 10001, 10001)
        os.chmod(p, 0o400)
    with urllib.request.urlopen('https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem', timeout=30) as response:
        ca = response.read()
    p = root / 'ca.pem'
    p.write_bytes(ca)
    os.chown(p, 10001, 10001)
    os.chmod(p, 0o400)
    registry = config['image'].split('/')[0]
    password = run(aws + ['ecr', 'get-login-password'], capture_output=True).stdout
    login_dir = tempfile.mkdtemp(prefix='three-tier-ecr-', dir='/run')
    try:
        run(['docker', '--config', login_dir, 'login', '--username', 'AWS', '--password-stdin', registry],
            input=password, stdout=subprocess.DEVNULL)
        run(['docker', '--config', login_dir, 'pull', config['image']])
    finally:
        shutil.rmtree(login_dir)
    for kind in ('api', 'worker'):
        name = 'orders-' + kind
        names = run(['docker', 'ps', '-a', '--format', '{{.Names}}'], capture_output=True, text=True).stdout.splitlines()
        if name in names:
            run(['docker', 'stop', '-t', '45', name])
            run(['docker', 'rm', name])
        command = ['docker', 'run', '-d', '--name', name, '--restart', 'unless-stopped',
                   '--user', '10001:10001', '--read-only', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges:true',
                   '--memory', '384m', '--cpus', '0.75', '--pids-limit', '128',
                   '--log-opt', 'max-size=10m', '--log-opt', 'max-file=3',
                   '--tmpfs', '/tmp:uid=10001,gid=10001,mode=0700',
                   '-e', 'WRITER_EPOCH=1', '-e', f'DATABASE_URL_FILE=/run/secrets/{kind}.dsn',
                   '-v', f'{root / (kind + ".dsn")}:/run/secrets/{kind}.dsn:ro',
                   '-v', f'{root / "ca.pem"}:/run/secrets/ca.pem:ro']
        if kind == 'api':
            command += ['-e', 'AUTH_FILE=/run/secrets/auth.json',
                        '-v', f'{root / "auth.json"}:/run/secrets/auth.json:ro', '-p', '8080:8080']
        command += [config['image']]
        if kind == 'worker':
            command += ['/app/worker']
        run(command)
    print('API and worker started; verify target health and business acceptance')


if __name__ == '__main__':
    main()
