import numpy
import re

def IsFloat(text):
  if text is None:
    return False
  try:
    float(text)
    return True
  except ValueError:
    return False


def RemoveTrailingZeros(x):
  ret = x
  ret = re.sub("\.0*$", "", ret)
  ret = re.sub("(\.[1-9]*)0+$", "\\1", ret)
  return ret


def HumanizeFloat(x, n=2):
  if not IsFloat(x):
    return x
  digits = re.findall("[0-9.]", str(x))
  decimal_found = False
  ret = ""
  sig_figs = 0
  for digit in digits:
    if digit == ".":
      decimal_found = True
    elif sig_figs != 0 or digit != "0":
      sig_figs += 1
    if decimal_found and sig_figs >= n:
      break
    ret += digit
  return ret


def GetNSigFigs(x, n=2):
  if not IsFloat(x):
    return x
  my_fmt = "%." + str(n-1) + "e"
  x_string = my_fmt % x
  f = float(x_string)
  return f


def GetFormattedPercent(baseline, other, bad_result="--"):
  result = "%8s" % GetPercent(baseline, other, bad_result)
  return result


def GetPercent(baseline, other, bad_result="--"):
  result = bad_result
  if IsFloat(baseline) and IsFloat(other):
    try:
      pct = (float(other)/float(baseline) - 1) * 100
      result = "%+1.1f" % pct
    except ZeroDivisionError:
      pass
  return result


def FitString(text, length):
  if len(text) == length:
    return text
  elif len(text) > length:
    return text[-length:]
  else:
    fmt = "%%%ds" % length
    return fmt % text


class TableFormatter(object):
  def __init__(self):
    self.d = "\t"
    self.bad_result = "x"

  def GetTablePercents(self, table):
    # Assumes table is not transposed.
    pct_table = []

    pct_table.append(table[0])
    for i in range(1, len(table)):
      row = []
      row.append(table[i][0])
      for j in range (1, len(table[0])):
        c = table[i][j]
        b = table[i][1]
        p = GetPercent(b, c, self.bad_result)
        row.append(p)
      pct_table.append(row)
    return pct_table

  def FormatFloat(self, c, max_length=8):
    if not IsFloat(c):
      return c
    f = float(c)
    ret = HumanizeFloat(f, 4)
    ret = RemoveTrailingZeros(ret)
    if len(ret) > max_length:
      ret = "%1.1ef" % f
    return ret

  def TransposeTable(self, table):
    transposed_table = []
    for i in range(len(table[0])):
      row = []
      for j in range(len(table)):
        row.append(table[j][i])
      transposed_table.append(row)
    return transposed_table

  def GetTableLabels(self, table):
    ret = ""
    header = table[0]
    for i in range(1, len(header)):
      ret += "%d: %s\n" % (i, header[i])
    return ret

  def GetFormattedTable(self, table, transposed=False,
                        first_column_width=30, column_width=14,
                        percents_only=True,
                        fit_string=True):
    o = ""
    pct_table = self.GetTablePercents(table)
    if transposed == True:
      table = self.TransposeTable(table)
      pct_table = self.TransposeTable(table)

    for i in range(0, len(table)):
      for j in range(len(table[0])):
        if j == 0:
          width = first_column_width
        else:
          width = column_width

        c = table[i][j]
        p = pct_table[i][j]

        # Replace labels with numbers: 0... n
        if IsFloat(c):
          c = self.FormatFloat(c)

        if IsFloat(p) and not percents_only:
          p = "%s%%" % p

        # Print percent values side by side.
        if j != 0:
          if percents_only:
            c = "%s" % p
          else:
            c = "%s (%s)" % (c, p)

        if i == 0 and j != 0:
          c = str(j)

        if fit_string:
          o += FitString(c, width) + self.d
        else:
          o += c + self.d
      o += "\n"
    return o

  def GetGroups(self, table):
    labels = table[0]
    groups = []
    group_dict = {}
    for i in range(1, len(labels)):
      label = labels[i]
      stripped_label = self.GetStrippedLabel(label)
      if stripped_label not in group_dict:
        group_dict[stripped_label] = len(groups)
        groups.append([])
      groups[group_dict[stripped_label]].append(i)
    return groups

  def GetSummaryTableValues(self, table):
    # First get the groups
    groups = self.GetGroups(table)

    summary_table = []

    labels = table[0]

    summary_labels = ["Summary Table"]
    for group in groups:
      label = labels[group[0]]
      stripped_label = self.GetStrippedLabel(label)
      group_label = "%s (%d runs)" % (stripped_label, len(group))
      summary_labels.append(group_label)
    summary_table.append(summary_labels)

    for i in range(1, len(table)):
      row = table[i]
      summary_row = [row[0]]
      for group in groups:
        group_runs = []
        for index in group:
          group_runs.append(row[index])
        group_run = self.AggregateResults(group_runs)
        summary_row.append(group_run)
      summary_table.append(summary_row)

    return summary_table

  # Drop N% slowest and M% fastest numbers, and return arithmean of
  # the remaining.
  @staticmethod
  def AverageWithDrops(numbers, slow_percent=20, fast_percent=20):
    sorted_numbers = list(numbers)
    sorted_numbers.sort()
    num_slow = int(slow_percent/100.0 * len(sorted_numbers))
    num_fast = int(fast_percent/100.0 * len(sorted_numbers))
    sorted_numbers = sorted_numbers[num_slow:]
    if num_fast:
      sorted_numbers = sorted_numbers[:-num_fast]
    return numpy.average(sorted_numbers)

  @staticmethod
  def AggregateResults(group_results):
    ret = ""
    if not group_results:
      return ret
    all_floats = True
    all_passes = True
    all_fails = True
    for group_result in group_results:
      if not IsFloat(group_result):
        all_floats = False
      if group_result != "PASSED":
        all_passes = False
      if group_result != "FAILED":
        all_fails = False
    if all_floats == True:
      float_results = [float(v) for v in group_results]
      ret = "%f" % TableFormatter.AverageWithDrops(float_results)
      # Add this line for standard deviation.
###      ret += " %f" % numpy.std(float_results)
    elif all_passes == True:
      ret = "ALL_PASS"
    elif all_fails == True:
      ret = "ALL_FAILS"
    return ret

  @staticmethod
  def GetStrippedLabel(label):
    return re.sub("\s*\S+:\S+\s*", "", label)
###    return re.sub("\s*remote:\S*\s*i:\d+$", "", label)

  @staticmethod
  def GetLabelWithIteration(label, iteration):
    return "%s i:%d" % (label, iteration)
