# -*- coding: utf-8 -*-
# Copyright 2011 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""The class to show the banner."""

from __future__ import division
from __future__ import print_function

import collections
import datetime
import time


class ExperimentStatus(object):
  """The status class."""

  def __init__(self, experiment):
    self.experiment = experiment
    self.num_total = len(self.experiment.benchmark_runs)
    self.completed = 0
    self.new_job_start_time = time.time()
    self.log_level = experiment.log_level

  def _GetProgressBar(self, num_complete, num_total):
    ret = 'Done: %s%%' % int(100.0 * num_complete / num_total)
    bar_length = 50
    done_char = '>'
    undone_char = ' '
    num_complete_chars = bar_length * num_complete // num_total
    num_undone_chars = bar_length - num_complete_chars
    ret += ' [%s%s]' % (num_complete_chars * done_char,
                        num_undone_chars * undone_char)
    return ret

  def GetProgressString(self):
    """Get the elapsed_time, ETA."""
    current_time = time.time()
    if self.experiment.start_time:
      elapsed_time = current_time - self.experiment.start_time
    else:
      elapsed_time = 0
    try:
      if self.completed != self.experiment.num_complete:
        self.completed = self.experiment.num_complete
        self.new_job_start_time = current_time
      time_completed_jobs = (
          elapsed_time - (current_time - self.new_job_start_time))
      # eta is calculated as:
      #   ETA = (num_jobs_not_yet_started * estimated_time_per_job)
      #          + time_left_for_current_job
      #
      #   where
      #        num_jobs_not_yet_started = (num_total - num_complete - 1)
      #
      #        estimated_time_per_job = time_completed_jobs / num_run_complete
      #
      #        time_left_for_current_job = estimated_time_per_job -
      #                                    time_spent_so_far_on_current_job
      #
      #  The biggest problem with this calculation is its assumption that
      #  all jobs have roughly the same running time (blatantly false!).
      #
      #  ETA can come out negative if the time spent on the current job is
      #  greater than the estimated time per job (e.g. you're running the
      #  first long job, after a series of short jobs).  For now, if that
      #  happens, we set the ETA to "Unknown."
      #
      eta_seconds = (
          float(self.num_total - self.experiment.num_complete - 1) *
          time_completed_jobs / self.experiment.num_run_complete +
          (time_completed_jobs / self.experiment.num_run_complete -
           (current_time - self.new_job_start_time)))

      eta_seconds = int(eta_seconds)
      if eta_seconds > 0:
        eta = datetime.timedelta(seconds=eta_seconds)
      else:
        eta = 'Unknown'
    except ZeroDivisionError:
      eta = 'Unknown'
    strings = []
    strings.append('Current time: %s Elapsed: %s ETA: %s' %
                   (datetime.datetime.now(),
                    datetime.timedelta(seconds=int(elapsed_time)), eta))
    strings.append(
        self._GetProgressBar(self.experiment.num_complete, self.num_total))
    return '\n'.join(strings)

  def GetStatusString(self):
    """Get the status string of all the benchmark_runs."""
    status_bins = collections.defaultdict(list)
    for benchmark_run in self.experiment.benchmark_runs:
      status_bins[benchmark_run.timeline.GetLastEvent()].append(benchmark_run)

    status_strings = []
    for key, val in status_bins.items():
      if key == 'RUNNING':
        get_description = self._GetNamesAndIterations
      else:
        get_description = self._GetCompactNamesAndIterations
      status_strings.append('%s: %s' % (key, get_description(val)))

    thread_status = ''
    thread_status_format = 'Thread Status: \n{}\n'
    if (self.experiment.schedv2() is None and
        self.experiment.log_level == 'verbose'):
      # Add the machine manager status.
      thread_status = thread_status_format.format(
          self.experiment.machine_manager.AsString())
    elif self.experiment.schedv2():
      # In schedv2 mode, we always print out thread status.
      thread_status = thread_status_format.format(
          self.experiment.schedv2().threads_status_as_string())

    result = '{}{}'.format(thread_status, '\n'.join(status_strings))

    return result

  def _GetNamesAndIterations(self, benchmark_runs):
    strings = []
    t = time.time()
    for benchmark_run in benchmark_runs:
      t_last = benchmark_run.timeline.GetLastEventTime()
      elapsed = str(datetime.timedelta(seconds=int(t - t_last)))
      strings.append("'{0}' {1}".format(benchmark_run.name, elapsed))
    return ' %s (%s)' % (len(strings), ', '.join(strings))

  def _GetCompactNamesAndIterations(self, benchmark_runs):
    grouped_benchmarks = collections.defaultdict(list)
    for benchmark_run in benchmark_runs:
      grouped_benchmarks[benchmark_run.label.name].append(benchmark_run)

    output_segs = []
    for label_name, label_runs in grouped_benchmarks.items():
      strings = []
      benchmark_iterations = collections.defaultdict(list)
      for benchmark_run in label_runs:
        assert benchmark_run.label.name == label_name
        benchmark_name = benchmark_run.benchmark.name
        benchmark_iterations[benchmark_name].append(benchmark_run.iteration)
      for key, val in benchmark_iterations.items():
        val.sort()
        iterations = ','.join(str(v) for v in val)
        strings.append('{} [{}]'.format(key, iterations))
      output_segs.append('  ' + label_name + ': ' + ', '.join(strings) + '\n')

    return ' %s \n%s' % (len(benchmark_runs), ''.join(output_segs))
