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

from __future__ import print_function

import argparse
import logging
import mimetypes
import os
import re
import subprocess
import sys
import tempfile

# Add third_party directory to the Python import path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import jinja2

# Oldest version of this directory that works for serving. Used to limit git
# history searches.
FIRST_REVISION = '08a37e09f110ab9cb2af3180f054f26a2fd274d6'
TEST_SUBDIR = 'webxr-samples'
INDEX_TEMPLATE = 'bucket_index.html'
LATEST_TEMPLATE = 'bucket_latest.html'

# Google Cloud storage bucket destination.
BUCKET = 'gs://chromium-webxr-test'

# URL templates used for creating the index page.
LINK_OMAHAPROXY = ('https://storage.googleapis.com/'
                   'chromium-find-releases-static/index.html#%s')
LINK_CRREV = 'https://crrev.com/%s'
LINK_CHROMIUMDASH = 'https://chromiumdash.appspot.com/commit/%s'

CR_POSITION_RE = re.compile(r'^Cr-Commit-Position:.*\#(\d+)')
BUCKET_COPY_RE = re.compile(r'^r(\d+)')

WINDOWS_EXES = {
  'git': 'git.bat',
  'gsutil.py': 'gsutil.py.bat',
}

SUFFIX_TYPES = {
  'js': 'application/javascript',
  'css': 'text/css',
  'html': 'text/html',
}

g_flags = None

def binary_name(cmd):
  """Finds the platform-appropriate name for an executable command."""

  # On Windows, the "subprocess" execution requires a name with extension.
  # Since we just need a couple of commands, use a simple replacement that
  # work for Chromium build environments. This isn't a general solution.
  if sys.platform != 'win32':
    return cmd
  if cmd in WINDOWS_EXES:
    return WINDOWS_EXES[cmd]
  raise Exeption('No known Windows executable for command "%s"' % cmd)

def run_command(*args):
  """Runs a shell command and returns output."""
  platform_args = list(args)
  platform_args[0] = binary_name(platform_args[0])
  logging.debug('Executing: %s', platform_args)
  return subprocess.check_output(platform_args)

def run_readonly(*args):
  """Runs command expected to have no side effects, safe for dry runs."""
  return run_command(*args)

def run_modify(*args):
  """Runs command with side effects, skipped for dry runs."""
  if g_flags.dry_run:
    print('Dry-Run:', *args)
    return
  return run_command(*args)

def get_cr_positions():
  """Retrieves list of Cr-Commit-Position entries for local commits"""
  revs = run_readonly('git', 'log', '--format=%H', FIRST_REVISION+'^..', '--',
                      TEST_SUBDIR)
  cr_positions = []
  for rev in revs.splitlines():
    cr_position = None
    msg = run_readonly('git', 'show', '-s', '--format=%B', rev)
    for line in msg.splitlines():
      m = CR_POSITION_RE.match(line)
      if m:
        cr_position = m.group(1)
    cr_positions.append(cr_position)
  return cr_positions

def get_commit_from_cr_position(position):
  """Given the Cr-Commit-Position, returns a string with commit hash.

  The function works on a best-effort basis. If commit hash cannot be found,
  it will return an empty string.

  Args:
    position: String containing Cr-Commit-Position number."""
  try:
    git_hash = run_readonly('git', 'crrev-parse', position).strip()
    logging.debug('`git crrev-parse %s` returned hash %s', position, git_hash)
    return git_hash
  except subprocess.CalledProcessError:
    logging.debug('`git crrev-parse %s` returned an error', position)
    return ''

def get_bucket_copies():
  """Retrieves list of test subdirectories from Cloud Storage"""
  copies = []
  dirs = run_readonly('gsutil.py', 'ls', '-d', BUCKET)
  strip_len = len(BUCKET) + 1
  for rev in dirs.splitlines():
    pos = rev[strip_len:]
    m = BUCKET_COPY_RE.search(pos)
    if m:
      copies.append(m.group(1))
  return copies

def is_working_dir_clean():
  """Checks if the git working directory has unsaved changes"""
  status = run_readonly('git', 'status', '--porcelain', '--untracked-files=no')
  return status.strip() == ''

def write_to_bucket(cr_position):
  """Copies the test directory to Cloud Storage"""
  destination = BUCKET + '/r' + cr_position
  run_modify('gsutil.py', '-m', 'rsync', '-x', 'media', '-r', './' + TEST_SUBDIR,
          destination)

  # The copy used mime types based on system-local mappings which may be
  # misconfigured. Sanity check and fix if needed.
  check_and_fix_content_types(destination)

def direct_publish_samples(source, dest_subfolder):
  destination = 'gs://chromium-webxr-samples' + '/' + dest_subfolder
  run_modify('gsutil.py', '-m', 'rsync', '-x', 'media', '-r', './' + source,
          destination)

  # The copy used mime types based on system-local mappings which may be
  # misconfigured. Sanity check and fix if needed.
  check_and_fix_content_types(destination)

def check_and_fix_content_types(destination):
  mimetypes.init()
  for suffix, content_type in SUFFIX_TYPES.iteritems():
    configured_type = mimetypes.types_map.get('.' + suffix)
    if configured_type != content_type:
      logging.info('Fixing content type mismatch for .%s: found %s, '
                   'expected %s.' % (suffix, configured_type, content_type))
      run_modify('gsutil.py', '-m', 'setmeta', '-h',
                 'Content-type:' + content_type,
                 destination + '/**.' + suffix)

def write_index():
  """Updates Cloud Storage index.html based on available test copies"""
  cr_positions = get_bucket_copies()
  cr_positions.sort(key=int, reverse=True)
  logging.debug('Index: %s', cr_positions)

  items = []

  for pos in cr_positions:
    rev = 'r' + pos
    links = []
    links.append({'href': '%s/index.html' % rev,
                  'anchor': 'index.html'})
    links.append({'href': LINK_CRREV % pos,
                  'anchor': '[crrev]'})
    links.append({'href': LINK_OMAHAPROXY % rev,
                  'anchor': '[find in releases]'})
    commit_hash = get_commit_from_cr_position(pos)
    if commit_hash:
      links.append({'href': LINK_CHROMIUMDASH % commit_hash,
                    'anchor' : '[chromium dash]'})
    items.append({'text': rev, 'links': links})

  template = jinja2.Template(open(INDEX_TEMPLATE).read())
  content = template.render({'items': items})
  logging.debug('index.html content:\n%s', content)

  with tempfile.NamedTemporaryFile(suffix='.html', delete=False) as temp:
    try:
      temp.write(content)
      temp.seek(0)
      temp.close()
      run_modify('gsutil.py', 'cp', temp.name, BUCKET + '/index.html')
    finally:
      os.unlink(temp.name)

def write_latest():
  """Updates Cloud Storage latest.html based on available test copies, pointing
  to the latest copy."""
  cr_positions = get_bucket_copies()
  cr_positions.sort(key=int, reverse=True)
  logging.debug('Index: %s', cr_positions)

  if not cr_positions:
    logging.debug('No cr_positions found, skipping generation of latest.html')
    return

  logging.debug('Latest cr position: %s', cr_positions[0])

  template = jinja2.Template(open(LATEST_TEMPLATE).read())
  content = template.render({'revisionString' : cr_positions[0]})
  logging.debug('latest.html content:\n%s', content)

  with tempfile.NamedTemporaryFile(suffix='.html', delete=False) as temp:
    try:
      temp.write(content)
      temp.seek(0)
      temp.close()
      run_modify('gsutil.py', 'cp', temp.name, BUCKET + '/latest.html')
    finally:
      os.unlink(temp.name)

def update_test_copies():
  """Uploads a new test copy if available"""

  if not is_working_dir_clean() and not g_flags.ignore_unclean_status:
    raise Exception('Working directory is not clean, check "git status"')

  cr_positions = get_cr_positions()
  logging.debug('Found git commit positions: %s', cr_positions)
  if not cr_positions:
    raise Exception('No commit positions found')

  latest_cr_position = cr_positions[0]
  if latest_cr_position is None and not g_flags.force_destination_cr_position:
    raise Exception('Top commit has no Cr-Commit-Position. Sync to tip of tree?')

  existing_copies = get_bucket_copies()
  logging.debug('Found bucket copies: %s', existing_copies)

  out_cr_position = g_flags.force_destination_cr_position or latest_cr_position

  need_index_update = False
  if out_cr_position in existing_copies:
    logging.info('Destination "r%s" already exists, skipping write',
                 out_cr_position)
  else:
    write_to_bucket(out_cr_position)
    need_index_update = True

  return need_index_update

def numeric_string(value):
  """Ensure value is a string containing an integer."""
  # This is used for validating flag values - the usual idiom would be to use
  # "type=int", but that would convert the value to an integer, and it's more
  # convenient to keep it string-valued for use in concatenation elsewhere.
  # Throws an exception if the integer conversion fails.
  return str(int(value))

def main():
  parser = argparse.ArgumentParser(
      description="""
Copies the current '%s' content to a Google Cloud Storage bucket
subdirectory named after the Cr-Commit-Position, and writes an index.html file
linking to the known test directories, newest first.

The intended workflow is as follows:

- Create a CL that modifies the webxr_test_pages content. Ideally, if this
  reflects an incompatible WebXR API change, the code change and test change
  should be combined in the same CL.

- After review, submit the CL as usual.

- Rebase, or check out a fresh branch that includes the merged CL. The
  "git log" history of the webxr_test_pages should contain the merged CL and
  its Cr-Commit-Position, and there should be no local commits in the history.

- Run this script to upload the new test snapshot and update the index.html
  file to include it.

The script has sanity checks to confirm that the state is as expected. It will
not overwrite existing data, you need to manually remove bad or incomplete
content from failed uploads using the cloud console before retrying.
""" % TEST_SUBDIR,
      formatter_class=argparse.RawDescriptionHelpFormatter)

  parser.add_argument('-v', '--verbose', action="store_true",
                      help="Print debugging info")
  parser.add_argument('-n', '--dry-run', action="store_true",
                      help="Don't run state-changing commands")
  parser.add_argument('--update-index-only', action="store_true",
                      help=("Generate a new index.html file based on already "
                            "existing directories, ignoring local changes"))
  parser.add_argument('--ignore-unclean-status', action="store_true",
                      help=("Proceed with copy even if there are uncommitted "
                            "local changes in the git working directory"))
  parser.add_argument('--force-destination-cr-position', metavar='NUMBER',
                      type=numeric_string,
                      help=("Force writing current content to the specified "
                            "destination CR position instead of determining "
                            "the name based on local git history, bypassing "
                            "history sanity checks"))
  parser.add_argument('--bucket', default=BUCKET,
                      help=("Destination Cloud Storage location, including "
                            "'gs://' prefix"))
  parser.add_argument('--direct-publish-samples-source', default=None,
                      help=("Publish samples from this folder directly to a "
                            "bucket."))
  parser.add_argument('--direct-publish-samples-dest', default=None,
                      help=("Publish samples directly to this subfolder in the "
                            "chromium-webxr-samples bucket."))

  global g_flags
  g_flags = parser.parse_args()

  if g_flags.verbose:
    logging.basicConfig(level=logging.DEBUG)

  if not os.path.isdir(TEST_SUBDIR):
    raise Exception('Must be run from webxr_test_pages directory')

  node_modules = os.path.join(TEST_SUBDIR, 'js', 'cottontail', 'node_modules')
  if os.path.isdir(node_modules):
    raise Exception('Please delete the obsolete directory "%s"' % node_modules)

  if g_flags.direct_publish_samples_source and g_flags.direct_publish_samples_dest:
    direct_publish_samples(
      g_flags.direct_publish_samples_source,
      g_flags.direct_publish_samples_dest)
    return

  need_index_update = False
  if g_flags.update_index_only:
    need_index_update = True
  else:
    need_index_update = update_test_copies()

  # Create an index.html file covering all found test copies.
  if need_index_update:
    write_index()
    write_latest()
  else:
    logging.info('No changes, skipping index.html and latest.html update.')


if __name__ == '__main__':
  main()
