#!/usr/bin/env python

"""Use multipass or lxc to setup uaclients running ubuntu-advantage-client"""

import argparse
import glob
import os
import re
import sys

MACAROON_DEPS = {
 'trusty': ['python3-libnacl', 'libsodium18'],
 'xenial': ['python3-libnacl', 'libsodium18'],
 'bionic': ['python3-libnacl', 'libsodium23'],
 'disco': ['python3-libnacl', 'libsodium23']}


try:
    from uaclient import util
except ImportError:
    # Add out cwd to path for dev tools
    _tdir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
    sys.path.insert(0, _tdir)
    from uaclient import util

PROG='run-uaclient'


def get_parser():
    """Build an arg parser for run-uaclient utility."""
    parser = argparse.ArgumentParser(
        prog=PROG,
        description='Create an lxc or kvm runing uaclient')
    parser.add_argument(
        '--backend', '-b', required=False, default='lxc',
        choices=['multipass', 'lxc'],
        help=('The backend to talk to when creating a vm: multipass or lxc. '
              'Default:"lxc"'))
    parser.add_argument(
        '--series', '-s', required=False, default='bionic',
        help='The Ubuntu series to deploy in the vm. Default: bionic')
    parser.add_argument(
        '--name', '-n',
        help='The name of the vm to create. Default: uaclient-<series>')
    return parser


def get_vm_name(backend, desired_name=None):
    """Find the appropriate unique vm name which doesn't aleady exist."""
    vm_list, _err = util.subp([backend, 'list'])
    if desired_name not in vm_list:
        return desired_name
    match = re.match(r'[^\d]+(\d+)', desired_name)
    if not match:
        base_id = 1
        desired_basename = desired_name
    else:
        base_id = match[0]
        desired_basename = desired_name.replace(base_id, '')
    while desired_name in vm_list:
         base_id = int(base_id) + 1
         desired_name = '%s%d' % (desired_basename, base_id)
    return desired_name


def create_uaclient_vm(backend, series, name=None):
    """Create a uaclient named uaclient vm if absent.

    @param backend: multipass or lxc
    @param series: Ubuntu series to deploy
    @param name: Name of the vm

    """
    cmd = []
    if not name:
        name = 'uaclient-%s' % series
    name = get_vm_name(backend, name)
    if series == 'trusty':
        debs = glob.glob('./ubuntu-advantage-tools*14.04.1_all.deb')
    else:
        debs = glob.glob('./ubuntu-advantage-tools*bddeb_all.deb')
    if not debs:
        raise RuntimeError(
            'Found no ubuntu-advantage-debs in ./,'
            ' try make deb and make deb-trusty')
    deb = os.path.basename(debs[0])
    if backend == 'multipass':
        util.subp(['multipass', 'launch', 'daily:%s' % series, '-n', name])
        util.subp(['multipass', 'copy-files', './%s' % deb,  '%s:.' % name])
        util.subp(['multipass', 'exec', name, '--', 'sudo', 'apt-get',
                   'install'] + MACAROON_DEPS[series])
        util.subp(['multipass', 'exec', name, '--', 'sudo', 'dpkg', '-i', deb])
        util.subp(['multipass', 'copy-files', 'uaclient-devel.conf',  '%s:.' % name])
        util.subp(['multipass', 'exec', name, '--', 'sudo', 'mv',
                   './uaclient-devel.conf',
                   '/etc/ubuntu-advantage/uaclient.conf'])
        print('Access demo uaclient with:\nmultipass exec %s -- bash -l' % name)
    elif backend == 'lxc':
        util.subp(['lxc', 'launch', 'ubuntu-daily:%s' % series, name])
        util.subp(['lxc', 'file', 'push', '%s' % deb, '%s/root/' % name])
        util.subp(['lxc', 'exec', name, '--', 'sudo', 'dpkg', '-i',
                   '/root/%s' % deb])
        util.subp(['lxc', 'file', 'push', 'uaclient-devel.conf',
                   '%s/etc/ubuntu-advantage/uaclient.conf' % name])
        print('Access demo uaclient with:\nlxc exec %s ua status' % name)
    else:
        raise ValueError("Invalid backend %s. Not multipass|lxc" % backend)


def main():
    """Tool to collect and tar all related logs."""
    parser = get_parser()
    args = parser.parse_args()
    create_uaclient_vm(args.backend, args.series, args.name)


if __name__ == '__main__':
    sys.exit(main())
