#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Configuration helper for Coturn daemon.
"""

import argparse
import json
import pathlib
import random
import shutil
import string

import augeas

from plinth import action_utils

CONFIG_FILE = pathlib.Path('/etc/coturn/freedombox.conf')


def parse_arguments():
    """Return parsed command line arguments as dictionary."""
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')

    subparsers.add_parser('setup', help='Setup Coturn server')
    subparsers.add_parser('get-config',
                          help='Return the current configuration')
    subparser = subparsers.add_parser('set-domain', help='Set the TLS domain')
    subparser.add_argument('domain_name', help='TLS domain name to set')

    subparsers.required = True
    return parser.parse_args()


def _key_path(key):
    """Return the augeas path for a key."""
    return '/files' + str(CONFIG_FILE) + '/' + key


def subcommand_setup(_):
    """Setup Coturn server."""
    CONFIG_FILE.parent.mkdir(exist_ok=True)
    if not CONFIG_FILE.exists():
        CONFIG_FILE.touch(0o640)
        shutil.chown(CONFIG_FILE, group='turnserver')

    action_utils.service_daemon_reload()
    action_utils.service_try_restart('coturn')

    aug = augeas_load()

    # XXX: Should we set listen, relay IP address to :: or dynamically
    # XXX: Should we set external-ip
    aug.set(_key_path('min-port'), '49152')
    aug.set(_key_path('max-port'), '50175')
    aug.set(_key_path('use-auth-secret'), 'true')
    if not aug.get(_key_path('static-auth-secret')):
        secret = ''.join(
            random.choice(string.ascii_letters + string.digits)
            for _ in range(64))
        aug.set(_key_path('static-auth-secret'), secret)

    aug.set(_key_path('cert'), '/etc/coturn/certs/cert.pem')
    aug.set(_key_path('pkey'), '/etc/coturn/certs/pkey.pem')
    aug.set(_key_path('no-tlsv1'), 'true')
    aug.set(_key_path('no-tlsv1_1'), 'true')
    aug.set(_key_path('no-cli'), 'true')

    aug.save()


def subcommand_get_config(_):
    """Return the current configuration in JSON format."""
    aug = augeas_load()
    config = {
        'static_auth_secret': aug.get(_key_path('static-auth-secret')),
        'realm': aug.get(_key_path('realm')),
    }
    print(json.dumps(config))


def subcommand_set_domain(arguments):
    """Set the TLS domain.

    This value is usually not stored. So, set realm value even though it is not
    needed to set realm for REST API based authentication.

    """
    aug = augeas_load()
    aug.set(_key_path('realm'), arguments.domain_name)
    aug.save()


def augeas_load():
    """Initialize Augeas."""
    aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
                        augeas.Augeas.NO_MODL_AUTOLOAD)
    aug.set('/augeas/load/Simplevars/lens', 'Simplevars.lns')
    aug.set('/augeas/load/Simplevars/incl[last() + 1]', str(CONFIG_FILE))
    aug.load()

    return aug


def main():
    """Parse arguments and perform all duties."""
    arguments = parse_arguments()

    subcommand = arguments.subcommand.replace('-', '_')
    subcommand_method = globals()['subcommand_' + subcommand]
    subcommand_method(arguments)


if __name__ == '__main__':
    main()
