# Copyright 2011 The Chromium OS 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 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.iteritems():
      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.iteritems():
      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.iteritems():
        val.sort()
        iterations = ','.join(map(str, val))
        strings.append('{} [{}]'.format(key, iterations))
      output_segs.append('  ' + label_name + ': ' + ', '.join(strings) + '\n')

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