"""
Tasks for working with a vagrant installation for testing and development.

:copyright: Copyright 2013-2015, Dorian Pula <dorian.pula@amber-penguin-software.ca>
:license: AGPL v3+
"""

import pathlib

import invoke as inv
from invoke import tasks

from . import deploy, utils


@inv.task
def start():
    """Start the Vagrant box."""
    with utils.cd('vagrant'):
        inv.run('vagrant up', echo=True, pty=True)


@inv.task
def stop():
    """Stop the Vagrant box."""
    with utils.cd('vagrant'):
        inv.run('vagrant halt', echo=True, pty=True)


@inv.task(stop)
def recreate(nuke_the_box=False):
    """Recreate the Vagrant box."""
    with utils.cd('vagrant'):
        inv.run('vagrant destroy', echo=True, pty=True)
        if nuke_the_box:
            inv.run('vagrant box remove ubuntu-server-trusty-64', echo=True, pty=True)
    inv.run('inv vagrant.install', echo=True, pty=True)


@inv.ctask(tasks.call(deploy.package, add_date_suffix=True), start)
def install(ctx, verbose=0):
    """Provision the vagrant box and deploy the Rookeries on the box."""
    install_ansible_roles()
    run_ansible_vagrant_playbook('provision.yaml', verbose, deployable=ctx.get('deployable'))


def generate_verbosity_tag(verbosity=0):
    if verbosity < 1:
        return ''
    return '-{}'.format('v' * min(verbosity, 4))


def run_ansible_vagrant_playbook(playbook, verbose, deployable=None):
    options = generate_verbosity_tag(verbose)
    if deployable:
        deploy_source = deployable.name.replace('.tar.bz2', '')
        options += ' --extra-vars "rookeries_deploy_source={} rookeries_package_path={} rookeries_"'.format(
            deploy_source, deployable.absolute())
    ansible_cmd = 'ansible-playbook-vagrant {playbook} {extra_opts}'.format(playbook=playbook, extra_opts=options)

    with utils.cd('vagrant'):
        inv.run('rm -rf hosts_vagrant', echo=True)
        inv.run(ansible_cmd, echo=True, pty=True)


def install_ansible_roles():
    EXTERNAL_ROLES_PATH = 'external_ansible_roles'
    ANSIBLE_ROLE_PATH_PARAM = '--roles-path={}'.format(EXTERNAL_ROLES_PATH)
    DEPENDENT_ROLES = {
        'rookeries': 'breakout-nodejs-role',
        'uwsgi-nginx-supervisor': 'split-out-nginx-supervisor-role',
        'nginx-supervisor': 'split-out-nginx-supervisor-role',
        'nodejs': 'master',
    }

    with utils.cd('vagrant'):
        external_role_folder = pathlib.Path(EXTERNAL_ROLES_PATH)
        if not external_role_folder.exists():
            external_role_folder.mkdir()
        listing_result = inv.run('ansible-galaxy list {}'.format(ANSIBLE_ROLE_PATH_PARAM))

        # if 'rookeries' not in listing_result.stdout:
        # TODO Fix once either ansible galaxy 2.1.0 works properly or role changes merged into master branches.
        # TODO See https://github.com/ansible/ansible/pull/10620 & https://github.com/ansible/ansible/issues/10477
        # inv.run('ansible-galaxy install {} -r role_requirements.yml'.format(ANSIBLE_ROLE_PATH_PARAM))

        for (role, branch) in DEPENDENT_ROLES.items():
            if role not in listing_result.stdout:
                git_cmd = 'git clone --branch {branch} https://bitbucket.org/dorianpula/ansible-{role} {path}/{role}'
                inv.run(git_cmd.format(branch=branch, role=role, path=EXTERNAL_ROLES_PATH))
