#!/usr/bin/env python3
#
# Copyright 2017 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.

"""This script can be used to upload CTS Verifier results to CTS Dashboard."""

from __future__ import print_function
from lib.upload_utils import UploadUtils
from xml.dom import minidom

import argparse
import getopt
import os.path
import sys


class UploadCtsVerifier(UploadUtils):
  """Helps upload CTS-V results to gs:// buckets.

  Prints CTS-V test results with their pass/fail status to terminal.
  Prints gsutil links to the terminal to upload CTS-V results to gs:// buckets
  to get the results in the tooling.

  Attributes:
    build_mismatch_exist: A boolean indicating if build mismatch exists.
    failed_tests_exist: A boolean indicating if failed tests exist.
    valid_files_exist: A boolean indicating if any valid file with the
                       correct build version exists.
    untested_tests_exist: A boolean indicating if untested tests exist.
    test_board_name_list: List of test board names.
  """

  def __init__(self):
    super(UploadCtsVerifier, self).__init__()
    self.build_mismatch_exist = False
    self.failed_tests_exist = False
    self.valid_files_exist = False
    self.untested_tests_exist = False
    self.test_board_name_list = []

  def PrintBuildInfoList(self):
    """Sorts build information by build board and prints to the terminal."""
    self.build_info_list.sort(key=lambda x: x[1])
    for item in self.build_info_list:
      if item[1] not in self.test_board_name_list:
        title_msg = 'List of files for %s' % item[1]
        table_column_header = self.TABLE_HEADER_CTSV
        print(self.BOLD +
              self.C_PURPLE +
              title_msg +
              self.BOLD +
              self.C_END)
        print(self.BOLD +
              self.C_BLACK +
              table_column_header +
              self.BOLD +
              self.C_END)

        self.test_board_name_list.append(item[1])
        self.PrintFormattedDataCtsv(item)
    print('\n')

  def PrintGsutilLinks(self, dir_path):
    """Prints gsutil links to upload results to CTS-V dashboard bucket.

    Args:
      dir_path: Results directory path.
    """
    for item in self.build_info_list:
      gsutil_msg = ('gsutil cp -r {0}/{1}_{2}/ '
                    'gs://chromeos-cts-results/ctsVerifier'
                    .format(dir_path, item[2], item[1]))
      print(self.BOLD + self.C_PURPLE + gsutil_msg + self.BOLD + self.C_END)

  def PrintIfAllTestsPassed(self):
    """Print message to terminal if all tests have passed."""
    if not self.failed_tests_exist and self.build_mismatch_file_count == 0:
      print('All Cts Verifier Tests passed!')

  def PrintFailedTestResults(self, tests):
    """Prints failed results if any to the terminal.

    Args:
      tests: CTS Verifier Test Results.
    """
    test_title = ' '
    result = ' '
    for test in tests:
      test_title = test.getAttribute('name')
      result = test.getAttribute('result')
      if result == 'fail' or result == 'not-executed':
        self.failed_tests_exist = True
        print('Test Title:%s, Result:%s' % (test_title, result))
        print('\n')

  def ParseXmlFile(self, abs_input_file_path, dir_path):
    """Gets build information from CTS Verifier xml file.

    Parses the CTS Verifier Xml File to obtain Build Information such as
    basename, build_board, build_id, suite_version.

    Args:
      abs_input_file_path: Absolute Input file path.
                           Eg: ~/Downloads/ctsv/2017.09.21_17.13.04-
                           CTS_VERIFIER-google-relm-relm_cheets-R62-9901.20.0
      dir_path: Results directory path.
                Eg: ~/Downloads/Manual

    Returns:
      tests: CTS Verifier Test Results.
    """
    test_result_filename_n_build = 'test_result.xml'
    tag_list = self.GetXmlTagNamesCtsv()
    build_version = tag_list[0]
    result = tag_list[1]
    suite_version = tag_list[2]
    build_board = tag_list[3]
    build_id_n = tag_list[4]
    test = tag_list[5]
    split_file_list = self.SplitFileName(abs_input_file_path)
    basename = split_file_list[1]
    full_base_name = os.path.join(dir_path, basename)
    basename_xml_file = split_file_list[2]
    absolute_base_xml_file = os.path.join(dir_path, basename_xml_file)
    self.CopyFileToDestination(full_base_name,
                               test_result_filename_n_build,
                               dir_path,
                               basename_xml_file)
    xml_doc = minidom.parse(absolute_base_xml_file)
    build = xml_doc.getElementsByTagName(build_version)
    verifier_info = xml_doc.getElementsByTagName(result)
    suite_version = verifier_info[0].attributes[suite_version].value
    build_board = build[0].attributes[build_board].value
    build_id = build[0].attributes[build_id_n].value
    tests = xml_doc.getElementsByTagName(test)
    self.UpdateBuildInfoList(
        [basename, build_board, build_id, suite_version])
    return tests

  def ProcessFilesToUpload(self, input_build_id, dir_path):
    """Process Files to Upload to CTS Verifier Bucket.

    Parses the test_result.xml file to obtain build information.
    Pushes valid files to appropriate folders to upload to CTS-V bucket.
    Pushes invalid files to Obsolete Folder.
    Print Build results to terminal.

    Args:
      input_build_id: Build ID for which results are to be uploaded.
      dir_path: Results directory path.
    """
    build_id = ' '
    item = ' '
    for the_file in os.listdir(dir_path):
      if the_file.endswith('.zip'):
        full_file = os.path.join(dir_path, the_file)
        self.ExtractZipFile(full_file, dir_path)
        tests = self.ParseXmlFile(the_file, dir_path)
        for item in self.build_info_list:
          build_id = item[2]
        if build_id == input_build_id:
          self.valid_files_exist = True
          self.failed_tests_exist = False
          self.CreateCtsFolder(full_file, dir_path)
          self.PrintBuildInfoList()
          self.PrintFailedTestResults(tests)
          self.PrintIfAllTestsPassed()
        else:
          self.build_mismatch_exist = True
          self.build_info_list.remove(item)
          self.CreateObsoleteFolder(full_file, dir_path)

def main(argv):
  """Processes result files and prints gsutil links to upload CTS-V results.

    Displays help message when script is called without expected arguments.
    Displays Usage: upload_cts_verifier.py <build_id> <results_dir_path>
  """
  parser = argparse.ArgumentParser()
  parser.add_argument('build_id',
                      help='Usage: upload_cts_verifier.py'
                           '<build_id>'
                           '<results_dir_path>')
  parser.add_argument('dir_path',
                      help='Usage: upload_cts_verifier.py'
                           '<build_id>'
                           '<results_dir_path>')
  args = parser.parse_args()
  input_build_id = args.build_id
  dir_path = args.dir_path
  if len(sys.argv) == 1:
    parser.print_help()
    sys.exit(1)
  parser.parse_args()
  try:
    opts, args = getopt.getopt(argv, 'hb:', ['buildID='])
  except getopt.GetoptError:
    print('upload_cts_verifier.py <build_id> <results_dir_path>')
    sys.exit(2)
  ctsv = UploadCtsVerifier()
  for opt in opts:
    if opt == '-h':
      ctsv.usage()
      sys.exit()
  ctsv.ProcessFilesToUpload(input_build_id, dir_path)
  if ctsv.valid_files_exist is True:
    ctsv.PrintGsutilLinks(dir_path)
  if ctsv.build_mismatch_exist is True:
    ctsv.PrintObsoleteFolderCount()

if __name__ == '__main__':
  main(sys.argv[1:])
