# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

import sys

import click

from polyaxon_cli.cli.check import check_polyaxonfile, get_group_experiments_info
from polyaxon_cli.cli.upload import upload
from polyaxon_cli.logger import clean_outputs
from polyaxon_cli.managers.project import ProjectManager
from polyaxon_cli.utils.clients import PolyaxonClients
from polyaxon_cli.utils.formatting import Printer
from polyaxon_client.exceptions import PolyaxonHTTPError, PolyaxonShouldExitError
from polyaxon_schemas.experiment import ExperimentConfig
from polyaxon_schemas.job import JobConfig
from polyaxon_schemas.project import ExperimentGroupConfig


@click.command()
@click.option('--file', '-f', multiple=True, type=click.Path(exists=True),
              help='The polyaxon files to run.')
@click.option('--description', type=str,
              help='The description to give to this run.')
@click.option('-u', is_flag=True, default=False,
              help='To upload the repo before running.')
@click.pass_context
@clean_outputs
def run(ctx, file, description, u):  # pylint:disable=redefined-builtin
    """Run polyaxonfile specification.

    Example:

    \b
    ```bash
    $ polyaxon run -f file -f file_override ...
    ```

    Example: upload before running

    \b
    ```bash
    $ polyaxon run -f file -u
    ```

    """
    file = file or 'polyaxonfile.yml'
    specification = check_polyaxonfile(file, log=False).specification

    spec_cond = (specification.is_experiment or
                 specification.is_group or
                 specification.is_job or
                 specification.is_build)
    if not spec_cond:
        Printer.print_error(
            'This command expects an experiment, a group, a job, or a build specification,'
            'received instead a `{}` specification'.format(specification.kind))
        if specification.is_notebook:
            click.echo('Please check "polyaxon notebook --help" to start a notebook.')
        elif specification.is_tensorboard:
            click.echo('Please check: "polyaxon tensorboard --help" to start a tensorboard.')
        sys.exit(1)

    # Check if we need to upload
    if u:
        ctx.invoke(upload, async=False)

    project = ProjectManager.get_config_or_raise()
    project_client = PolyaxonClients().project

    def run_experiment():
        click.echo('Creating an independent experiment.')
        experiment = ExperimentConfig(
            description=description,
            config=specification.parsed_data)
        try:
            response = PolyaxonClients().project.create_experiment(project.user,
                                                                   project.name,
                                                                   experiment)
            Printer.print_success('Experiment `{}` was created'.format(response.id))
        except (PolyaxonHTTPError, PolyaxonShouldExitError) as e:
            Printer.print_error('Could not create experiment.')
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    def run_group():
        click.echo('Creating an experiment group with the following definition:')
        experiments_def = specification.experiments_def
        get_group_experiments_info(**experiments_def)
        experiment_group = ExperimentGroupConfig(
            description=description,
            content=specification._data)  # pylint:disable=protected-access
        try:
            response = project_client.create_experiment_group(project.user,
                                                              project.name,
                                                              experiment_group)
            Printer.print_success('Experiment group {} was created'.format(response.id))
        except (PolyaxonHTTPError, PolyaxonShouldExitError) as e:
            Printer.print_error('Could not create experiment group.')
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    def run_job():
        click.echo('Creating a job.')
        job = JobConfig(
            description=description,
            config=specification.parsed_data)
        try:
            response = project_client.create_job(project.user,
                                                 project.name,
                                                 job)
            Printer.print_success('Job {} was created'.format(response.id))
        except (PolyaxonHTTPError, PolyaxonShouldExitError) as e:
            Printer.print_error('Could not create job.')
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    def run_build():
        click.echo('Creating a build.')
        job = JobConfig(
            description=description,
            config=specification.parsed_data)
        try:
            response = project_client.create_build(project.user,
                                                   project.name,
                                                   job)
            Printer.print_success('Build {} was created'.format(response.id))
        except (PolyaxonHTTPError, PolyaxonShouldExitError) as e:
            Printer.print_error('Could not create build.')
            Printer.print_error('Error message `{}`.'.format(e))
            sys.exit(1)

    if specification.is_experiment:
        run_experiment()
    elif specification.is_group:
        run_group()
    elif specification.is_job:
        run_job()
    elif specification.is_build:
        run_build()

@@ -847,87 +847,303 @@
 ('--
-description', type=str,%0A              help='The description to give to this run
+name', type=str,%0A              help='Name to give to this run, must be unique within the project, could be none.')%0A@click.option('--description', type=str,%0A              help='The description to give to this run.')%0A@click.option('--tags', type=str, help='Tags of this run, comma separated values
 .')%0A
@@ -1301,16 +1301,28 @@
 x, file,
+ name, tags,
  descrip
@@ -2685,32 +2685,55 @@
 perimentConfig(%0A
+            name=name,%0A
             desc
@@ -2745,32 +2745,55 @@
 on=description,%0A
+            tags=tags,%0A
             conf
@@ -3636,32 +3636,55 @@
 entGroupConfig(%0A
+            name=name,%0A
             desc
@@ -3696,32 +3696,55 @@
 on=description,%0A
+            tags=tags,%0A
             cont
@@ -4437,32 +4437,55 @@
 ob = JobConfig(%0A
+            name=name,%0A
             desc
@@ -4497,32 +4497,55 @@
 on=description,%0A
+            tags=tags,%0A
             conf
@@ -5154,39 +5154,85 @@
         
-description=description
+name=name,%0A            description=description,%0A            tags=tags
 ,%0A      

Allow to create run with names and tags