#!/usr/bin/env python3
# Copyright (c) 2012 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 extract a build, executed by a tester builder."""

import optparse
import os
import shutil
import sys
import traceback

# Add build/recipes and build/scripts.
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.abspath(os.path.join(THIS_DIR, '..', 'recipes')))
sys.path.insert(0, os.path.abspath(os.path.join(THIS_DIR, '..', 'scripts')))

from common import chromium_utils
import bot_utils
import build_directory


class ExtractHandler:

  def __init__(self, url, archive_name, gsutil_py_path):
    self.url = url
    self.archive_name = archive_name
    self.gsutil_py_path = gsutil_py_path

  def download(self):
    override_gsutil = [sys.executable, self.gsutil_py_path]
    status = bot_utils.GSUtilCopy(
        self.url, '.', override_gsutil=override_gsutil
    )
    if 0 != status:
      return False
    try:
      shutil.move(os.path.basename(self.url), self.archive_name)
    except OSError:
      os.remove(self.archive_name)
      shutil.move(os.path.basename(self.url), self.archive_name)
    return True


def GetBuildUrl(options, build_revision):
  """Compute the url to download the build from.  This will use as a base
     string, in order of preference:
     0) options.build_archive_url
     1) options.build_url
     2) options.build_properties.build_url
     3) build url constructed from build_properties.  This last type of
        construction is not compatible with the 'force build' button.

     Args:
       options: options object as specified by parser below.
       build_revision: Revision for the build.
  """
  if options.build_archive_url:
    return options.build_archive_url, None

  base_filename, version_suffix = bot_utils.GetZipFileNames(build_revision)

  url = options.build_url
  if url[-4:] != '.zip':  # assume filename not specified
    # Append the filename to the base URL. First strip any trailing slashes.
    url = url.rstrip('/')
    url = f'{url}/{base_filename}.zip'
  archive_name = url.split('/')[-1]
  versioned_url = url.replace('.zip', version_suffix + '.zip')
  return versioned_url, archive_name


def real_main(options):
  """ Download a build, extract it to build\\BuildDir\\full-build-win32
      and rename it to build\\BuildDir\\Target
  """
  abs_build_dir = os.path.abspath(
      build_directory.GetBuildOutputDirectory(options.src_dir)
  )
  target_build_output_dir = os.path.join(abs_build_dir, options.target)

  # Generic name for the archive.
  archive_name = 'full-build-%s.zip' % chromium_utils.PlatformName()

  # Just take the zip off the name for the output directory name.
  output_dir = os.path.join(abs_build_dir, archive_name.replace('.zip', ''))

  src_dir = os.path.dirname(abs_build_dir)
  if not options.build_revision and not options.build_archive_url:
    build_revision = bot_utils.GetBuildRevisions(src_dir)
  else:
    build_revision = options.build_revision
  url, archive_name = GetBuildUrl(options, build_revision)
  if archive_name is None:
    archive_name = 'build.zip'

  if not url.startswith('gs://'):
    print(
        f'cannot extract build from {url},'
        ' only Google Storage URLs are supported'
    )
    return bot_utils.ERROR_EXIT_CODE

  handler = ExtractHandler(
      url=url,
      archive_name=archive_name,
      gsutil_py_path=options.gsutil_py_path,
  )

  # We try to download and extract 3 times.
  for tries in range(1, 4):
    print('Try %d: Fetching build from %s...' % (tries, url))

    # If the url is valid, we download the file.
    if not handler.download():
      return bot_utils.ERROR_EXIT_CODE

    print('Extracting build %s to %s...' % (archive_name, abs_build_dir))
    try:
      chromium_utils.RemoveDirectory(target_build_output_dir)
      chromium_utils.ExtractZip(archive_name, abs_build_dir)
      # For Chrome builds, the build will be stored in chrome-win32.
      if 'full-build-win32' in output_dir:
        chrome_dir = output_dir.replace('full-build-win32', 'chrome-win32')
        if os.path.exists(chrome_dir):
          output_dir = chrome_dir

      print(
          'Moving build from %s to %s' % (output_dir, target_build_output_dir)
      )
      shutil.move(output_dir, target_build_output_dir)
    except (OSError, IOError, chromium_utils.ExternalError):
      print('Failed to extract the build.')
      # Print out the traceback in a nice format
      traceback.print_exc()
      # Try again...
      continue

    return 0

  # If we get here, that means that it failed 3 times. We return a failure.
  return bot_utils.ERROR_EXIT_CODE


def main():
  option_parser = optparse.OptionParser()

  option_parser.add_option(
      '--target', help='build target to archive (Debug or Release)'
  )
  option_parser.add_option(
      '--src-dir',
      default='src',
      help='path to the top-level sources directory'
  )
  option_parser.add_option('--build-dir', help='ignored')
  option_parser.add_option(
      '--build-url', help='Base url where to find the build to extract'
  )
  option_parser.add_option(
      '--build-archive-url',
      help='Exact url where to find the build to extract'
  )
  option_parser.add_option(
      '--build_revision',
      help='Revision of the build that is being '
      'archived. Overrides the revision found on '
      'the local disk'
  )
  option_parser.add_option(
      '--revision-dir',
      help=(
          'Directory path that shall be used to decide '
          'the revision number for the archive, '
          'relative to the src/ dir.'
      )
  )
  option_parser.add_option('--build-output-dir', help='ignored')
  option_parser.add_option(
      '--gsutil-py-path', help='Specify path to gsutil.py script.'
  )
  chromium_utils.AddPropertiesOptions(option_parser)

  options, args = option_parser.parse_args()
  if args:
    print('Unknown options: %s' % args)
    return 1
  if not options.gsutil_py_path:
    print('--gsutil-py-path must be specified')
    return 1

  if not options.build_url:
    options.build_url = options.build_properties.get('build_url')
  if not options.target:
    options.target = options.build_properties.get('target', 'Release')
  options.src_dir = (
      options.build_properties.get('extract_build_src_dir') or options.src_dir
  )

  if not options.build_archive_url and not options.build_url:
    print('At least one of --build-archive-url or --build-url must be passed')
    return 1

  return real_main(options)


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