# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.

from datetime import datetime
from os.path import getmtime, isdir, join
from shutil import rmtree
from time import time

import click

from platformio import app, exception, telemetry, util
from platformio.commands.install import cli as cmd_install
from platformio.platforms.base import PlatformFactory


@click.command("run", short_help="Process project environments")
@click.option("--environment", "-e", multiple=True, metavar="<environment>")
@click.option("--target", "-t", multiple=True, metavar="<target>")
@click.option("--upload-port", metavar="<upload port>")
@click.pass_context
def cli(ctx, environment, target, upload_port):

    config = util.get_project_config()

    if not config.sections():
        raise exception.ProjectEnvsNotAvailable()

    unknown = set(environment) - set([s[4:] for s in config.sections()])
    if unknown:
        raise exception.UnknownEnvNames(", ".join(unknown))

    # remove ".pioenvs" if project config is modified
    _pioenvs_dir = util.get_pioenvs_dir()
    if (isdir(_pioenvs_dir) and
            getmtime(join(util.get_project_dir(), "platformio.ini")) >
            getmtime(_pioenvs_dir)):
        rmtree(_pioenvs_dir)

    _first_processing = True
    for section in config.sections():
        # skip main configuration section
        if section == "platformio":
            continue
        elif section[:4] != "env:":
            raise exception.InvalidEnvName(section)

        envname = section[4:]
        if environment and envname not in environment:
            # echo("Skipped %s environment" % style(envname, fg="yellow"))
            continue

        options = {}
        for k, v in config.items(section):
            options[k] = v

        process_environment(ctx, envname, options, target, upload_port)

        if not _first_processing:
            click.echo()
        _first_processing = False


def process_environment(ctx, name, options, targets, upload_port):
    terminal_width, _ = click.get_terminal_size()
    start_time = time()

    click.echo("[%s] Processing %s (%s)" % (
        datetime.now().strftime("%c"),
        click.style(name, fg="cyan", bold=True),
        ", ".join(["%s: %s" % (k, v) for k, v in options.iteritems()])
    ))
    click.secho("-" * terminal_width, bold=True)

    result = _run_environment(ctx, name, options, targets, upload_port)
    is_error = "error" in result['err'].lower()

    summary_text = " Took %.2f seconds " % (time() - start_time)
    half_line = "=" * ((terminal_width - len(summary_text) - 10) / 2)
    click.echo("%s [%s]%s%s" % (
        half_line,
        (click.style(" ERROR ", fg="red", bold=True)
         if is_error else click.style("SUCCESS", fg="green", bold=True)),
        summary_text,
        half_line
    ), err=is_error)


def _run_environment(ctx, name, options, targets, upload_port):
    variables = ["PIOENV=" + name]
    if upload_port:
        variables.append("UPLOAD_PORT=%s" % upload_port)
    for k, v in options.items():
        k = k.upper()
        if k == "TARGETS" or (k == "UPLOAD_PORT" and upload_port):
            continue
        variables.append("%s=%s" % (k.upper(), v))

    envtargets = []
    if targets:
        envtargets = [t for t in targets]
    elif "targets" in options:
        envtargets = options['targets'].split()

    if "platform" not in options:
        raise exception.UndefinedEnvPlatform(name)
    platform = options['platform']

    telemetry.on_run_environment(options, envtargets)

    installed_platforms = PlatformFactory.get_platforms(
        installed=True).keys()
    if (platform not in installed_platforms and (
            not app.get_setting("enable_prompts") or
            click.confirm("The platform '%s' has not been installed yet. "
                          "Would you like to install it now?" % platform))):
        ctx.invoke(cmd_install, platforms=[platform])

    p = PlatformFactory.newPlatform(platform)
    return p.run(variables, envtargets)

@@ -1259,24 +1259,19 @@
 rst_
-processing = Tru
+done = Fals
 e%0A  
@@ -1768,16 +1768,66 @@
 k%5D = v%0A%0A
+        if _first_done:%0A            click.echo()%0A%0A
         
@@ -1890,25 +1890,24 @@
 d_port)%0A
-%0A
         
 if not _
@@ -1902,91 +1902,25 @@
     
-if not _first_processing:%0A            click.echo()%0A        _first_processing = Fals
+_first_done = Tru
 e%0A%0A%0A

Correct divisor between multiple envs