#!/usr/bin/env vpython3
# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""This script updates network traffic annotations sheet. To run the script, you
should first generate annotations.tsv using traffic_annotation_auditor, and then
call:
update_annotations_sheet --config=[settings.json] [path_to_annotations.tsv]

Run update_annotations_sheet --config-help for help on configuration file.

TODO(rhalavati): Add tests.
"""

from __future__ import print_function

import argparse
import csv
import datetime
import httplib2
import io
import json
import os
import re
import sys

from apiclient import discovery
from infra_libs import luci_auth
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from generator_utils import load_tsv_file


SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
SRC_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../../.."))


def GetCurrentChromeVersion():
  with io.open(os.path.join(SRC_DIR, "chrome/VERSION")) as f:
    contents = f.read()
  version_parts = dict(
      re.match(r"(\w+)=(\d+)", line).groups() for line in contents.split("\n")
      if line)
  return tuple(
      int(version_parts[part]) for part in ["MAJOR", "MINOR", "BUILD", "PATCH"])


def VersionTupleToString(version_tuple):
  return '.'.join(map(str, version_tuple))


class SheetEditor():
  """Loads and updates traffic annotation's sheet."""

  # If modifying these scopes, delete your previously saved credentials.
  SCOPES = "https://www.googleapis.com/auth/spreadsheets"
  APPLICATION_NAME = "Chrome Network Traffic Annotations Spreadsheet Updater"

  def __init__(self, spreadsheet_id, annotations_sheet_name,
               chrome_version_sheet_name, silent_change_columns,
               last_update_column_name, credentials_file_path,
               client_secret_file_path, verbose):
    """ Initializes the SheetEditor. Please refer to 'PrintConfigHelp' function
    for description of input arguments.

    Args:
      spreadsheet_id: str
          ID of annotations spreadsheet.
      annotations_sheet_name: str
          Name of the sheet that contains the annotations.
      chrome_version_sheet_name: str
          Name of the sheet that contains the changes stats.
      silent_change_columns: list of str
          List of the columns whose changes are not reported in the stats.
      last_update_column_name: str
          Header of the column that keeps the latest update date.
      credentials_file_path: str
          Absolute path to read/save user credentials.
      client_secret_file_path: str
          Absolute path to read client_secret.json.
      verbose: bool
          Flag requesting dump of details of actions.
    """
    print("Getting credential to update annotations report.")
    self.service = self._InitializeService(
        self._GetCredentials(credentials_file_path, client_secret_file_path))
    print("Successfully got credential to update annotations report.")
    self.spreadsheet_id = spreadsheet_id
    self.annotations_sheet_name = annotations_sheet_name
    self.chrome_version_sheet_name = chrome_version_sheet_name
    self.silent_change_columns = silent_change_columns
    self.last_update_column_name = last_update_column_name
    self.annotations_sheet_id = self._GetAnnotationsSheetId()
    self.required_row_updates = []
    self.required_cell_updates = []
    self.delete_count = 0
    self.insert_count = 0
    self.update_count = 0
    self.verbose = verbose
    self.today = datetime.datetime.now().strftime("%m/%d/%Y")


  def _InitializeService(self, credentials):
    """ Initializes the Google Sheets API service.

    Args:
      credentials: OAuth2Credentials user credentials.

    Returns:
      googleapiclient.discovery.Resource Spreadsheet API service.
    """
    http = credentials.authorize(httplib2.Http())
    discoveryUrl = ("https://sheets.googleapis.com/$discovery/rest?version=v4")
    return discovery.build("sheets", "v4", http=http,
                           discoveryServiceUrl=discoveryUrl)


  def _GetCredentials(self, credentials_file_path, client_secret_file_path):
    """ Gets valid user credentials from storage. If nothing has been stored, or
    if the stored credentials are invalid, the OAuth2 flow is completed to
    obtain the new credentials.

    When running in the buildbot, uses LUCI credentials instead.

    Args:
      credentials_file_path: str Absolute path to read/save user credentials.
      client_secret_file_path: str Absolute path to read client_secret.json.

    Returns:
      OAuth2Credentials The obtained user credentials.
    """
    if luci_auth.available():
      return luci_auth.LUCICredentials(scopes=[self.SCOPES])

    store = Storage(credentials_file_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
      flow = client.flow_from_clientsecrets(client_secret_file_path,
                                            self.SCOPES)
      flow.user_agent = self.APPLICATION_NAME
      flags = tools.argparser.parse_args([])
      credentials = tools.run_flow(flow, store, flags)
      print("Storing credentials to " + credentials_file_path)
    return credentials


  def _GetAnnotationsSheetId(self):
    """ Gets the id of the sheet containing annotations table.

    Returns:
      int Id of the sheet.
    """
    response = self.service.spreadsheets().get(
        spreadsheetId=self.spreadsheet_id,
        ranges=self.annotations_sheet_name,
        includeGridData=False).execute()
    return response["sheets"][0]["properties"]["sheetId"]


  def LoadAnnotationsSheet(self):
    """ Loads the sheet's content.

    Returns:
      list of list Table of annotations loaded from the trix.
    """
    result = self.service.spreadsheets().values().get(
        spreadsheetId=self.spreadsheet_id,
        range=self.annotations_sheet_name).execute()
    return result.get("values", [])


  def _CreateInsertRequest(self, row):
    self.required_row_updates.append(
        { "insertDimension": {
            "range": {
              "sheetId": self.annotations_sheet_id,
              "dimension": "ROWS",
              "startIndex": row, # 0 index.
              "endIndex": row + 1
            }
          }
        })
    self.insert_count += 1


  def _CreateAppendRequest(self, row_count):
    self.required_row_updates.append(
        { "appendDimension": {
            "sheetId": self.annotations_sheet_id,
            "dimension": "ROWS",
            "length": row_count
          }
        })
    self.insert_count += row_count


  def _CreateDeleteRequest(self, row):
    self.required_row_updates.append(
        { "deleteDimension": {
            "range": {
              "sheetId": self.annotations_sheet_id,
              "dimension": "ROWS",
              "startIndex": row,
              "endIndex": row + 1
            }
          }
        })
    self.delete_count += 1


  def _CreateUpdateRequest(self, row, column, value):
    # If having more than 26 columns, update cell_name.
    assert(column < 26)
    cell_name = "%s%i" % (chr(65 + column), 1 + row)
    self.required_cell_updates.append(
        { "range": "%s!%s:%s" % (
              self.annotations_sheet_name, cell_name, cell_name),
          "values": [[value]] })


  def GenerateUpdates(self, file_contents):
    """ Generates required updates to refresh the sheet, using the input file
    contents.

    Args:
      file_contents: list of list Table of annotations read from file. Each item
          represents one row of the annotation table, and each row is presented
          as a list of its column values.

    Returns:
      bool Flag specifying if everything was OK or not.
    """
    print("Generating updates for report.")
    sheet_contents = self.LoadAnnotationsSheet()
    if not sheet_contents:
      print("Could not read previous content.")
      return False

    headers = file_contents[0]
    silent_change_column_indices = []
    for title in self.silent_change_columns:
      if title not in headers:
        print("ERROR: Could not find %s column." % title)
        return False
      silent_change_column_indices.append(headers.index(title))

    last_update_column = headers.index(self.last_update_column_name)

    # Step 1: Compare old and new contents, generate add/remove requests so that
    # both contents would become the same size with matching unique ids (at
    # column 0).
    # Ignores header row (row 0).
    old_set = set(row[0] for row in sheet_contents[1:])
    new_set = set(row[0] for row in file_contents[1:])
    removed_ids = old_set - new_set
    added_ids = list(new_set - old_set)
    added_ids.sort()
    if self.verbose:
      for id in removed_ids:
        print("Deleted: %s" % id)
      for id in added_ids:
        print("Added: %s" % id)

    empty_row = [''] * len(file_contents[0])
    # Skip first row (it's the header row).
    row = 1
    while row < len(sheet_contents):
      row_id = sheet_contents[row][0]
      # If a row is removed, remove it from previous sheet.
      if row_id in removed_ids:
        self._CreateDeleteRequest(row)
        sheet_contents.pop(row)
        continue
      # If there are rows to add, and they should be before current row, insert
      # an empty row before current row. The empty row will be filled later.
      if added_ids and added_ids[0] < row_id:
        self._CreateInsertRequest(row)
        sheet_contents.insert(row, empty_row[:])
        added_ids.pop(0)
      row += 1

    # If there are still rows to be added, they should come at the end.
    if added_ids:
      self._CreateAppendRequest(len(added_ids))
      while added_ids:
        sheet_contents.append(empty_row[:])
        added_ids.pop()

    assert(len(file_contents) == len(sheet_contents))

    # Step 2: Compare cells of old and new contents, issue requests to update
    # cells with different values. Ignore headers row.
    for row in range(1, len(file_contents)):
      file_row = file_contents[row]
      sheet_row = sheet_contents[row]

      major_update = False
      for col in range(len(file_row)):
        # Ignore 'Last Update' column for now.
        if col == last_update_column:
          continue
        if file_row[col] != sheet_row[col]:
          self._CreateUpdateRequest(row, col, file_row[col])
          if self.verbose and sheet_row[0]:
            print("Updating: %s - %s" % (file_row[0], file_contents[0][col]))
          if col not in silent_change_column_indices:
            major_update = True
      # If there has been a change in a column that is not silently updated,
      # update the date as well.
      if major_update:
        self._CreateUpdateRequest(row, last_update_column, self.today)
        # If the row is not entirely new, increase the update count.
        if sheet_row[0]:
          self.update_count += 1
    return True


  def ApplyUpdates(self):
    """ Applies the updates stored in |self.required_row_updates| and
    |self.required_cell_updates| to the sheet.
    """
    # Insert/Remove rows.
    print("Applying updates for the report.")
    if self.required_row_updates:
      self.service.spreadsheets().batchUpdate(
          spreadsheetId=self.spreadsheet_id,
          body={"requests": self.required_row_updates}).execute()

    # Refresh Cells.
    if self.required_cell_updates:
      batch_update_values_request_body = {
        "value_input_option": "RAW",
        "data": self.required_cell_updates
      }
      self.service.spreadsheets().values().batchUpdate(
          spreadsheetId=self.spreadsheet_id,
          body=batch_update_values_request_body).execute()


  def GiveUpdateSummary(self):
    return "New annotations: %s, Modified annotations: %s, " \
           "Removed annotations: %s" % (
                self.insert_count, self.update_count, self.delete_count)


  def UpdateChromeVersion(self, version_tuple):
    self.service.spreadsheets().values().update(
        spreadsheetId=self.spreadsheet_id,
        range="%s!A1:A1" % self.chrome_version_sheet_name,
        valueInputOption="RAW",
        body={
            "values": [[VersionTupleToString(version_tuple)]]
        }).execute()

  def GetChromeVersionFromSheet(self):
    response = self.service.spreadsheets().values().get(
        spreadsheetId=self.spreadsheet_id,
        range="%s!A1:A1" % self.chrome_version_sheet_name).execute()
    version_string = response["values"][0][0]
    return tuple(int(part) for part in version_string.split('.'))


def PrintConfigHelp():
  print("The config.json file should have the following items:\n"
        "spreadsheet_id:\n"
        "  ID of annotations spreadsheet.\n"
        "annotations_sheet_name:\n"
        "  Name of the sheet that contains the annotations.\n"
        "chrome_version_sheet_name:\n"
        "  Name of the sheet that contains the Chrome version.\n"
        "silent_change_columns:\n"
        "  List of the columns whose changes don't affect the Last Update "
        "column.\n"
        "last_update_column_name:\n"
        "  Header of the column that keeps the latest update date.\n"
        "credentials_file_path:\n"
        "  Absolute path of the file that keeps user credentials.\n"
        "client_secret_file_path:\n"
        "  Absolute path of the file that keeps client_secret.json. The file\n"
        "  can be created as specified in:\n"
        "  https://developers.google.com/sheets/api/quickstart/python")


def main():
  parser = argparse.ArgumentParser(
      description="Network Traffic Annotations Sheet Updater")
  parser.add_argument(
      "--config-file",
      help="Configurations file.")
  parser.add_argument(
      "--annotations-file",
      help="TSV annotations file exported from auditor.")
  parser.add_argument(
      '--verbose', action='store_true',
      help='Reports all updates.')
  parser.add_argument('--yes',
                      action='store_true',
                      help='Performs all actions without confirmation.')
  parser.add_argument(
      '--force',
      action='store_true',
      help='Performs all actions without confirmation, regardless of the '
      'sheet being older or newer than this version. Implies --yes.')
  parser.add_argument(
      '--config-help', action='store_true',
      help='Shows the configurations help.')
  args = parser.parse_args()
  if args.force:
    args.yes = True

  print("Updating annotations sheet.")
  if args.config_help:
    PrintConfigHelp()
    return 0

  # Load and parse config file.
  with open(args.config_file) as config_file:
    config = json.load(config_file)

  # Load and parse annotations file.
  file_content = load_tsv_file(args.annotations_file, args.verbose)
  if not file_content:
    print("Could not read annotations file.")
    return -1

  sheet_editor = SheetEditor(
      spreadsheet_id=config["spreadsheet_id"],
      annotations_sheet_name=config["annotations_sheet_name"],
      chrome_version_sheet_name=config["chrome_version_sheet_name"],
      silent_change_columns=config["silent_change_columns"],
      last_update_column_name=config["last_update_column_name"],
      credentials_file_path=config.get("credentials_file_path", None),
      client_secret_file_path=config.get("client_secret_file_path", None),
      verbose=args.verbose)

  current_version = GetCurrentChromeVersion()
  current_version_string = VersionTupleToString(current_version)
  print("This is Chrome version %s" % current_version_string)

  sheet_version = sheet_editor.GetChromeVersionFromSheet()
  sheet_version_string = VersionTupleToString(sheet_version)
  print("Sheet contains Chrome version %s" % sheet_version_string)

  if sheet_version > current_version and not args.force:
    print("Sheet is already newer than this Chrome version. Aborting.")
    return 0

  if not sheet_editor.GenerateUpdates(file_content):
    print("Error generating updates for file content.")
    return -1

  main_sheet_needs_update = (sheet_editor.required_cell_updates
                             or sheet_editor.required_row_updates)
  version_needs_update = current_version != sheet_version

  if main_sheet_needs_update or version_needs_update:
    if main_sheet_needs_update:
      print("%s" % sheet_editor.GiveUpdateSummary())
    else:
      print("No updates to annotations required.")

    if current_version != sheet_version:
      print("The '%s' sheet will be updated to '%s'." %
            (sheet_editor.chrome_version_sheet_name, current_version_string))

    if not args.yes:
      print("Proceed with update?")
      if raw_input("(Y/n): ").strip().lower() != "y":
        return -1

    if main_sheet_needs_update:
      sheet_editor.ApplyUpdates()
    if version_needs_update:
      sheet_editor.UpdateChromeVersion(current_version)
    print("Updates applied.")

  else:
    print("No updates required.")

  return 0


if __name__ == "__main__":
  sys.exit(main())
