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

import click

from anaconda_enterprise.cli import internal, parse
from anaconda_enterprise.cli.api import _list, create_client

ERROR_ = click.style('ERROR', fg='red')
SUCCESS_ = click.style('success', fg='green')


def _list_uploads(uploads, what='package'):
    _list(('Name', 'Uploaded (UTC)'), ('name', 'uploaded'),
          uploads,
          action='uploaded',
          what='package')


@click.command(name='upload')
@click.option('--channel', help="Upload to a specific channel")
@click.argument('package', type=click.Path(exists=True), nargs=-1)
@click.option('--ignore-name', help="Will not check the name of the file")
@click.pass_obj  # object in context is the Configuration Manager
def upload(config_manager, channel, package, ignore_name):
    """Upload a conda package"""
    sys.exit(_upload(config_manager, channel, package, ignore_name))


def _upload(config_manager, channel, package, ignore_name):
    """Upload a conda package"""
    try:
        default_channel = config_manager['default_channel']
    except KeyError:
        pass
    else:
        if channel is None:
            channel = default_channel
    client = create_client(config_manager)
    chan = client.get_channel(channel)
    if chan is None:
        click.echo('Error: invalid channel {0}.'.format(channel))
        return
    uploads = []
    for pkg in package:
        pkg_name = os.path.basename(pkg)
        try:
            click.echo('Uploading {0}...'.format(pkg_name), nl=False)
            attrs = parse.parse_conda(pkg, ignore_name_validation=ignore_name)
            upload = client.stage_file(chan, attrs)
            # upload icon file if it exists
            if 'has-icon' in attrs['recipe-attributes']:
                client.upload_icon(upload, pkg)
            # upload package file
            with open(pkg, 'rb') as fd:
                client.upload_file(upload, fd)
            uploads.append((pkg_name, datetime.datetime.utcnow().isoformat()))
            click.echo(SUCCESS_)
        except (internal.ServerError, ValueError,
                internal.JSONAPIError) as exc:
            exc = str(exc).replace('\n', '\n| ')
            click.echo('{0}\n| {1}'.format(ERROR_, exc))
    if uploads:
        _list_uploads(uploads)
    else:
        click.echo('No packages uploaded.')
    return 0 if len(uploads) == len(package) else 1


@click.command(name='upload_pypi')
@click.option('--pypi-index', help="Upload to a specific index", required=True)
@click.argument('package', type=click.Path(exists=True), nargs=-1)
@click.option('--ignore-name', help="Will not check the name of the file")
@click.pass_obj  # object in context is the Configuration Manager
def upload_pypi(config_manager, pypi_index, package, ignore_name):
    """Upload a pypi package"""
    client = create_client(config_manager)
    pypi_index = client.get_pypi_index(pypi_index)
    uploads = []
    for pkg in package:
        pkg_name = os.path.basename(pkg)
        try:
            click.echo('Uploading {0}...'.format(pkg_name), nl=False)
            attrs = parse.parse_pypi(pkg)
            upload = client.stage_pypi_file(pypi_index, attrs)
            with open(pkg, 'rb') as fd:
                client.upload_file(upload, fd)
            uploads.append((pkg_name, datetime.datetime.utcnow().isoformat()))
            click.echo(SUCCESS_)
        except (internal.ServerError, ValueError,
                internal.JSONAPIError) as exc:
            exc = str(exc).replace('\n', '\n| ')
            click.echo('{0}\n| {1}'.format(ERROR_, exc))
    if uploads:
        _list_uploads(uploads)
    else:
        click.echo('No packages uploaded.')
    sys.exit(0 if len(uploads) == len(package) else 1)
