# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright 2016 Continuum Analytics, Inc.
#
# May be copied and distributed freely only as part of an Anaconda or
# Miniconda installation.
# -----------------------------------------------------------------------------
import click

from anaconda_enterprise.cli.api import _list, create_client, pass_client


@click.group(name='packages')
@click.pass_context
def main(ctx):
    """Manage conda packages"""
    client = create_client(ctx.obj)
    ctx.obj = client


def _list_files(files):
    _list(('Name', 'Platform', 'Owner'), ('filename', 'subdir', 'owner'),
          [f['attributes'] for f in files])


def _list_packages(packages):
    _list(('Name', 'Version', 'Channel'), ('name', 'version', 'channel-name'),
          [(p['attributes']['name'], v, p['attributes']['channel-name'])
           for p in sorted(packages, key=lambda p: p['attributes']['name'])
           for v in (p['attributes']['versions'] or [''])])


def _file_action(action, number, what='file'):
    click.echo('{} {}{} {}.'.format(number, what, '' if number == 1 else 's',
                                    action))


def _get_channel(client, channel):
    chan = client.get_channel(channel)
    if chan is None:
        raise click.ClickException(
            'Channel "{}" was not found'.format(channel))
    return chan


def _get_files(client, channel, package, list=True):
    client.get_channel(channel)
    pkg = client.get_package(channel, package)
    files = client.list_files(pkg)
    if list:
        _list_files(files)
    return pkg, files


@main.command()
@pass_client
def list(client):
    packages = client.packages()
    _list_packages(packages)


@main.command()
@click.argument('channel')
@click.argument('package')
@click.option('--file', help='platform/filename to delete')
@pass_client
def delete(client, channel, package, file):
    if file and '/' not in file:
        raise click.ClickException(
            "--file argument must be of the form platform/filename: {}".format(
                file))
    pkg, files = _get_files(client, channel, package, list=False)
    olen = len(files)
    if file:
        subdir, filename = file.split('/', 1)
        files = [
            f for f in files if f.get('attributes', {}).get('subdir') == subdir
            and f.get('attributes', {}).get('filename') == filename
        ]
        if not files:
            raise click.ClickException('File not found: {}/{}'.format(
                channel, file))
    else:
        subdir = filename = None
    nlen = len(files)
    if olen == nlen:
        msg = "This will delete all files related to {0}/{1}:"
    else:
        msg = "This will delete the following file related to {0}/{1}:"
    click.echo(msg.format(channel, package))
    _list_files(files)
    click.confirm("Do you want to continue?", abort=True)
    client.delete_package(pkg, subdir, filename)
    _file_action('deleted', nlen)


@main.command()
@click.argument('src_channel')
@click.argument('src_subdir')
@click.argument('src_filename')
@click.argument('dst_channel')
@pass_client
def copyfile(client, src_channel, src_subdir, src_filename, dst_channel):
    if src_channel == dst_channel:
        raise click.ClickException(
            'Source and destination channels are identical')
    _get_channel(client, src_channel)
    chan = _get_channel(client, dst_channel)
    client.copy_pkg_file(src_channel, src_subdir, src_filename, chan['id'])
    _file_action('copied', 1)


@main.command()
@click.argument('src_channel')
@click.argument('src_pkg')
@click.argument('dst_channel')
@pass_client
def copy(client, src_channel, src_pkg, dst_channel):
    if src_channel == dst_channel:
        raise click.ClickException(
            'Source and destination channels are identical')
    chan = _get_channel(client, dst_channel)
    _, files = _get_files(client, src_channel, src_pkg, list=True)
    client.copy_pkg(src_channel, src_pkg, chan['id'])
    _file_action('copied', len(files))


@main.command(name="list-files")
@click.argument('src_channel')
@click.argument('src_pkg')
@pass_client
def listfiles(client, src_channel, src_pkg):
    _, files = _get_files(client, src_channel, src_pkg, list=True)
    _file_action('found', len(files))
