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

"""A tool to upload translation screenshots to Google Cloud Storage.

This tool searches the current repo for .png files associated with .grd or
.grdp files. It uploads the images to a Cloud Storage bucket and generates .sha1
files. Finally, it asks the user if they want to add the .sha1 files to their
CL.

Images must be named the same as the UI strings they represent
(e.g. IDS_HELLO.png for IDS_HELLO). The tool does NOT try to parse .grd/.grdp
files, so it doesn't know whether an image file corresponds to a message or not.
It will attempt to upload the image anyways.
"""

from __future__ import print_function

import argparse
import sys
import os
import subprocess

import helper.translation_helper as translation_helper

here = os.path.dirname(os.path.realpath(__file__))
src_path = os.path.normpath(os.path.join(here, '..', '..'))

depot_tools_path = os.path.normpath(
    os.path.join(src_path, 'third_party', 'depot_tools'))
sys.path.insert(0, depot_tools_path)

import upload_to_google_storage
import download_from_google_storage

sys.path.remove(depot_tools_path)

# Translation expectations file for the Chromium repo.
TRANSLATION_EXPECTATIONS_PATH = os.path.join('tools', 'gritsettings',
                                             'translation_expectations.pyl')

# URL of the bucket used for storing screenshots.
# This is writable by @google.com accounts, readable by everyone.
BUCKET_URL = 'gs://chromium-translation-screenshots'

if sys.platform.startswith('win'):
  # Use the |git.bat| in the depot_tools/ on Windows.
  GIT = 'git.bat'
else:
  GIT = 'git'


def query_yes_no(question, default='no'):
  """Ask a yes/no question via raw_input() and return their answer.

  "question" is a string that is presented to the user.
  "default" is the presumed answer if the user just hits <Enter>.
      It must be "yes" (the default), "no" or None (meaning
      an answer is required of the user).

  The "answer" return value is True for "yes" or False for "no".
  """
  if default is None:
    prompt = '[y/n] '
  elif default == 'yes':
    prompt = '[Y/n] '
  elif default == 'no':
    prompt = '[y/N] '
  else:
    raise ValueError("invalid default answer: '%s'" % default)

  valid = {'yes': True, 'y': True, 'ye': True, 'no': False, 'n': False}
  while True:
    print(question, prompt)
    choice = raw_input().lower()
    if default is not None and choice == '':
      return valid[default]
    elif choice in valid:
      return valid[choice]
    else:
      print("Please respond with 'yes' or 'no' (or 'y' or 'n').")


def list_grds_in_repository(repo_path):
  """Returns a list of all the grd files in the current git repository."""
  # This works because git does its own glob expansion even though there is no
  # shell to do it.
  output = subprocess.check_output(
      [GIT, 'ls-files', '--', '*.grd'], cwd=repo_path)
  return output.strip().splitlines()


def git_add(files, repo_root):
  """Adds relative paths given in files to the current CL."""
  # Upload in batches in order to not exceed command line length limit.
  BATCH_SIZE = 50
  added_count = 0
  while added_count < len(files):
    batch = files[added_count:added_count+BATCH_SIZE]
    command = [GIT, 'add'] + batch
    subprocess.check_call(command, cwd=repo_root)
    added_count += len(batch)


def find_screenshots(repo_root, translation_expectations):
  """Returns a list of translation related .png files in the repository."""
  translatable_grds = translation_helper.get_translatable_grds(
      repo_root, list_grds_in_repository(repo_root), translation_expectations)

  # Add the paths of grds and any files they include. This includes grdp files
  # and files included via <structure> elements.
  src_paths = []
  for grd in translatable_grds:
    src_paths.append(grd.path)
    src_paths.extend(grd.grdp_paths)
    src_paths.extend(grd.structure_paths)

  screenshots = []
  for grd_path in src_paths:
    # Convert grd_path.grd to grd_path_grd/ directory.
    name, ext = os.path.splitext(os.path.basename(grd_path))
    relative_screenshots_dir = os.path.relpath(
        os.path.dirname(grd_path), repo_root)
    screenshots_dir = os.path.realpath(
        os.path.join(repo_root,
                     os.path.join(relative_screenshots_dir,
                                  name + ext.replace('.', '_'))))
    # Grab all the .png files under the screenshot directory. On a clean
    # checkout this should be an empty list, as the repo should only contain
    # .sha1 files of previously uploaded screenshots.
    if not os.path.exists(screenshots_dir):
      continue
    for f in os.listdir(screenshots_dir):
      if f in ('OWNERS', 'README.md') or f.endswith('.sha1'):
        continue
      if not f.endswith('.png'):
        print('File with unexpected extension: %s in %s' % (f, screenshots_dir))
        continue
      screenshots.append(os.path.join(screenshots_dir, f))
  return screenshots


def main():
  parser = argparse.ArgumentParser(
      description='Upload translation screenshots to Google Cloud Storage')
  parser.add_argument(
      '-n',
      '--dry-run',
      action='store_true',
      help='Don\'t actually upload the images')
  args = parser.parse_args()

  screenshots = find_screenshots(src_path,
                                 os.path.join(src_path,
                                              TRANSLATION_EXPECTATIONS_PATH))
  if not screenshots:
    print ("No screenshots found.\n\n"
           "- Screenshots must be located in the correct directory.\n"
           "  E.g. For IDS_HELLO_WORLD message in path/to/file.grd, save the "
           "screenshot at path/to/file_grd/IDS_HELLO_WORLD.png.\n"
           "- If you added a new, uncommitted .grd file, `git add` it so that "
           "this script can pick up its screenshot directory.")
    exit(0)

  print('Found %d updated screenshot(s): ' % len(screenshots))
  for s in screenshots:
    print('  %s' % s)
  print()
  if not query_yes_no(
      'Do you want to upload these to Google Cloud Storage?\n\n'
      'FILES WILL BE PUBLIC, DO NOT UPLOAD ANYTHING CONFIDENTIAL.'):
    exit(0)

  # Creating a standard gsutil object, assuming there are depot_tools
  # and everything related is set up already.
  gsutil_path = os.path.abspath(os.path.join(depot_tools_path, 'gsutil.py'))
  gsutil = download_from_google_storage.Gsutil(gsutil_path, boto_path=None)

  if not args.dry_run:
    if upload_to_google_storage.upload_to_google_storage(
        input_filenames=screenshots,
        base_url=BUCKET_URL,
        gsutil=gsutil,
        force=False,
        use_md5=False,
        num_threads=10,
        skip_hashing=False,
        gzip=None) != 0:
      print ('Error uploading screenshots. Try running '
             '`download_from_google_storage --config`.')
      exit(1)

  print()
  print('Images are uploaded and their signatures are calculated:')

  signatures = ['%s.sha1' % s for s in screenshots]
  for s in signatures:
    print('  %s' % s)
  print()

  # Always ask if the .sha1 files should be added to the CL, even if they are
  # already part of the CL. If the files are not modified, adding again is a
  # no-op.
  if not query_yes_no('Do you want to add these files to your CL?',
                      default='yes'):
    exit(0)

  if not args.dry_run:
    git_add(signatures, src_path)

  print('DONE.')


if __name__ == '__main__':
  main()
