#!/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)


  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)
