#!/usr/bin/python
#
# Copyright 2013 Google Inc. All Rights Reserved.

"""Script to maintain the Telemetry benchmark default results file.

This script allows the user to see and update the set of default
results to be used in generating reports from running the Telemetry
benchmarks.

"""

__author__ = "cmtice@google.com (Caroline Tice)"

import os
import sys
import json

from utils import misc

Defaults = {}

DEFAULTS_FILE_NAME = 'crosperf/default-telemetry-results.json'

class TelemetryDefaults(object):

  def __init__(self):
    # Get the Crosperf directory; that is where the defaults
    # file should be.
    dirname, __ = misc.GetRoot(sys.argv[0])
    fullname = os.path.join(dirname, DEFAULTS_FILE_NAME)
    self._filename = fullname
    self._defaults = {}

  def ReadDefaultsFile (self):
    if os.path.exists(self._filename):
      with open(self._filename, "r") as fp:
        self._defaults = json.load(fp)


  def WriteDefaultsFile (self):
    with open(self._filename, "w") as fp:
      json.dump(self._defaults, fp, indent=2)


  def ListCurrentDefaults (self, benchmark=all):
    # Show user current defaults. By default, show all.  The user
    # can specify the name of a particular benchmark to see only that
    # benchmark's default values.
    if len(self._defaults) == 0:
      print ("The benchmark default results are currently empty.")
    if benchmark == all:
      for b in self._defaults.keys():
        results = self._defaults[b]
        out_str = b + ' : '
        for r in results:
          out_str +=  r + ' '
        print (out_str)
    elif benchmark in self._defaults:
      results = self._defaults[benchmark]
      out_str = benchmark + ' : '
      for r in results:
        out_str +=  r + ' '
      print (out_str)
    else:
      print ("Error:  Unrecognized benchmark '%s'" % benchmark)


  def AddDefault (self, benchmark, result):
    if benchmark in self._defaults:
      resultList = self._defaults[benchmark]
    else:
      resultList = []
    resultList.append(result)
    self._defaults[benchmark] = resultList
    print ("Updated results set for '%s': " % benchmark)
    print ("%s : %s" % (benchmark, repr(self._defaults[benchmark])))


  def RemoveDefault (self, benchmark, result):
    if benchmark in self._defaults:
      resultList = self._defaults[benchmark]
      if result in resultList:
        resultList.remove(result)
        print ("Updated results set for '%s': " % benchmark)
        print ("%s : %s" % (benchmark, repr(self._defaults[benchmark])))
      else:
        print ("'%s' is not in '%s's default results list." %
               (result, benchmark))
    else:
      print ("Cannot find benchmark named '%s'" % benchmark)

  def RemoveBenchmark (self, benchmark):
    if benchmark in self._defaults:
      del self._defaults[benchmark]
      print ("Deleted benchmark '%s' from list of benchmarks." % benchmark)
    else:
      print ("Cannot find benchmark named '%s'" % benchmark)

  def RenameBenchmark (self, old_name, new_name):
    if old_name in self._defaults:
      resultsList = self._defaults[old_name]
      del self._defaults[old_name]
      self._defaults[new_name] = resultsList
      print ("Renamed '%s' to '%s'." % (old_name, new_name))
    else:
      print ("Cannot find benchmark named '%s'" % old_name)

  def UsageError(self, user_input):
    # Print error message, then show options
    print ("Error:Invalid user input: '%s'" % user_input)
    self.ShowOptions()

  def ShowOptions (self):
    print """
Below are the valid user options and their arguments, and an explanation
of what each option does.  You may either print out the full name of the
option, or you may use the first letter of the option.  Case (upper or
lower) does not matter, for the command (case of the result name DOES matter):

    (L)ist                           - List all current defaults
    (L)ist <benchmark>               - List current defaults for benchmark
    (H)elp                           - Show this information.
    (A)dd <benchmark> <result>       - Add a default result for a particular
                                       benchmark (appends to benchmark's list
                                       of results, if list already exists)
    (D)elete <benchmark> <result>    - Delete a default result for a
                                       particular benchmark
    (R)emove <benchmark>             - Remove an entire benchmark (and its
                                       results)
    (M)ove <old-benchmark> <new-benchmark>    - Rename a benchmark
    (Q)uit                           - Exit this program, saving changes.
    (T)erminate                      - Exit this program; abandon changes.

"""

  def GetUserInput (self):
    # Prompt user
    print ("Enter option> ")
    # Process user input
    inp = sys.stdin.readline()
    inp = inp[:-1]
    # inp = inp.lower()
    words = inp.split(" ")
    option = words[0]
    option = option.lower()
    if option == 'h' or option == 'help':
      self.ShowOptions()
    elif option == 'l' or option == 'list':
      if len(words) == 1:
        self.ListCurrentDefaults()
      else:
        self.ListCurrentDefaults(benchmark=words[1])
    elif option == 'a' or option == 'add':
      if len(words) < 3:
        self.UsageError (inp)
      else:
        benchmark = words[1]
        resultList = words[2:]
        for r in resultList:
          self.AddDefault(benchmark, r)
    elif option == 'd' or option == 'delete':
      if len(words) != 3:
        self.UsageError (inp)
      else:
        benchmark = words[1]
        result = words[2]
        self.RemoveDefault(benchmark, result)
    elif option == 'r' or option == 'remove':
      if len(words) != 2:
        self.UsageError (inp)
      else:
        benchmark = words[1]
        self.RemoveBenchmark(benchmark)
    elif option == 'm' or option == 'move':
      if len(words) != 3:
        self.UsageError (inp)
      else:
        old_name = words[1]
        new_name = words[2]
        self.RenameBenchmark(old_name, new_name)
    elif option == 'q' or option == 'quit':
      self.WriteDefaultsFile()

    return (option == 'q' or option == 'quit' or option == 't' or
            option == 'terminate')


def Main():
  defaults = TelemetryDefaults()
  defaults.ReadDefaultsFile()
  defaults.ShowOptions()
  done = defaults.GetUserInput()
  while not done:
    done = defaults.GetUserInput()
  return 0

if __name__ == "__main__":
  retval = Main()
  sys.exit(retval)
