#!/usr/bin/env python
#
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Gets or updates a content shell (a nearly headless build of chrome). This is
# used for running browser tests of client applications.

import json
import optparse
import os
import platform
import shutil
import subprocess
import sys
import tempfile
import zipfile

import utils

def NormJoin(path1, path2):
  return os.path.normpath(os.path.join(path1, path2))

# Change into the dart directory as we want the project to be rooted here.
dart_src = NormJoin(os.path.dirname(sys.argv[0]), os.pardir)
os.chdir(dart_src)

GSUTIL_DIR = os.path.join('third_party', 'gsutil')
GSUTIL = GSUTIL_DIR + '/gsutil'

DRT_DIR = os.path.join('client', 'tests', 'drt')
DRT_VERSION = os.path.join(DRT_DIR, 'LAST_VERSION')
DRT_LATEST_PATTERN = (
    'gs://dartium-archive/latest/drt-%(osname)s-%(bot)s-*.zip')
DRT_PERMANENT_PATTERN = ('gs://dartium-archive/drt-%(osname)s-%(bot)s/drt-'
                         '%(osname)s-%(bot)s-%(num1)s.%(num2)s.zip')

DARTIUM_DIR = os.path.join('client', 'tests', 'dartium')
DARTIUM_VERSION = os.path.join(DARTIUM_DIR, 'LAST_VERSION')
DARTIUM_LATEST_PATTERN = (
    'gs://dartium-archive/latest/dartium-%(osname)s-%(bot)s-*.zip')
DARTIUM_PERMANENT_PATTERN = ('gs://dartium-archive/dartium-%(osname)s-%(bot)s/'
                             'dartium-%(osname)s-%(bot)s-%(num1)s.%(num2)s.zip')

SDK_DIR = os.path.join(utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32'),
    'dart-sdk')
SDK_VERSION = os.path.join(SDK_DIR, 'LAST_VERSION')
SDK_LATEST_PATTERN = 'gs://dart-archive/channels/dev/raw/latest/VERSION'
# TODO(efortuna): Once the x64 VM also is optimized, select the version
# based on whether we are running on a 32-bit or 64-bit system.
SDK_PERMANENT = ('gs://dart-archive/channels/dev/raw/%(version_num)s/sdk/' +
    'dartsdk-%(osname)s-ia32-release.zip')

# Dictionary storing the earliest revision of each download we have stored.
LAST_VALID = {'dartium': 4285, 'chromedriver': 7823, 'sdk': 9761, 'drt': 5342}

sys.path.append(os.path.join(GSUTIL_DIR, 'third_party', 'boto'))
import boto


def ExecuteCommand(*cmd):
  """Execute a command in a subprocess."""
  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  output, error = pipe.communicate()
  return pipe.returncode, output


def ExecuteCommandVisible(*cmd):
  """Execute a command in a subprocess, but show stdout/stderr."""
  result = subprocess.call(cmd, stdout=sys.stdout, stderr=sys.stderr,
                           stdin=sys.stdin)
  if result != 0:
    raise Exception('Execution of "%s" failed' % ' '.join(cmd))


def Gsutil(*cmd):
  return ExecuteCommand('python', GSUTIL, *cmd)


def GsutilVisible(*cmd):
  ExecuteCommandVisible('python', GSUTIL, *cmd)


def HasBotoConfig():
  """Returns true if boto config exists."""

  config_paths = boto.pyami.config.BotoConfigLocations
  if 'AWS_CREDENTIAL_FILE' in os.environ:
    config_paths.append(os.environ['AWS_CREDENTIAL_FILE'])
  for config_path in config_paths:
    if os.path.exists(config_path):
      return True

  return False


def InRunhooks():
  """True if this script was called by "gclient runhooks" or "gclient sync\""""
  return 'runhooks' in sys.argv


def GetDartiumRevision(name, bot, directory, version_file, latest_pattern,
    permanent_prefix, revision_num=None):
  """Get the latest binary that is stored in the dartium archive.

  Args:
    name: the name of the desired download.
    directory: target directory (recreated) to install binary
    version_file: name of file with the current version stamp
    latest_pattern: the google store url pattern pointing to the latest binary
    permanent_prefix: stable google store folder used to download versions
    revision_num: The desired revision number to retrieve. If revision_num is
        None, we return the latest revision. If the revision number is specified
        but unavailable, find the nearest older revision and use that instead.
  """
  osdict = {'Darwin':'mac-x64', 'Linux':'linux-x64', 'Windows':'win-ia32'}

  def FindPermanentUrl(out, osname, the_revision_num):
    output_lines = out.split()
    latest = output_lines[-1]
    if not the_revision_num:
      latest = (permanent_prefix[:permanent_prefix.rindex('/')] % { 'osname' :
          osname, 'bot' : bot } + latest[latest.rindex('/'):])
    else:
      latest = (permanent_prefix % { 'osname' : osname, 'num1' : the_revision_num,
          'num2' : the_revision_num, 'bot' : bot })
      foundURL = False
      while not foundURL:
        # Test to ensure this URL exists because the dartium-archive builds can
        # have unusual numbering (a range of CL numbers) sometimes.
        result, out = Gsutil('ls', permanent_prefix % {'osname' : osname,
            'num1': the_revision_num, 'num2': '*', 'bot': bot })
        if result == 0:
          # First try to find one with the second number the same as the
          # requested number.
          latest = out.split()[0]
          # Now test that the permissions are correct so you can actually
          # download it.
          temp_dir = tempfile.mkdtemp()
          temp_zip = os.path.join(temp_dir, 'foo.zip')
          returncode, out = Gsutil('cp', latest, 'file://' + temp_zip)
          if returncode == 0:
            foundURL = True
          else:
            # Unable to download this item (most likely because something went
            # wrong on the upload and the permissions are bad). Keep looking for
            # a different URL.
            the_revision_num = int(the_revision_num) - 1
          shutil.rmtree(temp_dir)
        else:
          # Now try to find one with a nearby CL num.
          the_revision_num = int(the_revision_num) - 1
          if the_revision_num <= 0:
            TooEarlyError()
    return latest

  GetFromGsutil(name, directory, version_file, latest_pattern, osdict,
                  FindPermanentUrl, revision_num, bot)


def GetSdkRevision(name, directory, version_file, latest_pattern,
    permanent_prefix, revision_num):
  """Get a revision of the SDK from the editor build archive.

  Args:
    name: the name of the desired download
    directory: target directory (recreated) to install binary
    version_file: name of file with the current version stamp
    latest_pattern: the google store url pattern pointing to the latest binary
    permanent_prefix: stable google store folder used to download versions
    revision_num: the desired revision number, or None for the most recent
  """
  osdict = {'Darwin':'macos', 'Linux':'linux', 'Windows':'win32'}
  def FindPermanentUrl(out, osname, not_used):
    rev_num = revision_num
    if not rev_num:
      temp_file = tempfile.NamedTemporaryFile(delete=False)
      temp_file.close()
      temp_file_url = 'file://' + temp_file.name
      Gsutil('cp', latest_pattern % {'osname' : osname }, temp_file_url)
      temp_file = open(temp_file.name)
      temp_file.seek(0)
      version_info = temp_file.read()
      temp_file.close()
      os.unlink(temp_file.name)
      if version_info != '':
        rev_num = json.loads(version_info)['revision']
      else:
        print 'Unable to get latest version information.'
        return ''
    latest = (permanent_prefix % { 'osname' : osname, 'version_num': rev_num})
    return latest

  GetFromGsutil(name, directory, version_file, latest_pattern, osdict,
                  FindPermanentUrl, revision_num)


def GetFromGsutil(name, directory, version_file, latest_pattern,
    os_name_dict, get_permanent_url, revision_num = '', bot = None):
  """Download and unzip the desired file from Google Storage.
    Args:
    name: the name of the desired download
    directory: target directory (recreated) to install binary
    version_file: name of file with the current version stamp
    latest_pattern: the google store url pattern pointing to the latest binary
    os_name_dict: a dictionary of operating system names and their corresponding
        strings on the google storage site.
    get_permanent_url: a function that accepts a listing of available files
        and the os name, and returns a permanent URL for downloading.
    revision_num: the desired revision number to get (if not supplied, we get
        the latest revision)
  """
  system = platform.system()
  try:
    osname = os_name_dict[system]
  except KeyError:
    print >>sys.stderr, ('WARNING: platform "%s" does not support'
        '%s.') % (system, name)
    return 0

  # Query for the latest version
  pattern = latest_pattern  % { 'osname' : osname, 'bot' : bot }
  result, out = Gsutil('ls', pattern)
  if result == 0:
    # use permanent link instead, just in case the latest zip entry gets deleted
    # while we are downloading it.
    latest = get_permanent_url(out, osname, revision_num)
  else: # e.g. no access
    print "Couldn't download %s: %s\n%s" % (name, pattern, out)
    if not os.path.exists(version_file):
      print "Using %s will not work. Please try again later." % name
    return 0

  # Check if we need to update the file
  if os.path.exists(version_file):
    v = open(version_file, 'r').read()
    if v == latest:
      if not InRunhooks():
        print name + ' is up to date.\nVersion: ' + latest
      return 0 # up to date

  # download the zip file to a temporary path, and unzip to the target location
  temp_dir = tempfile.mkdtemp()
  try:
    temp_zip = os.path.join(temp_dir, 'drt.zip')
    temp_zip_url = 'file://' + temp_zip
    # It's nice to show download progress
    GsutilVisible('cp', latest, temp_zip_url)

    if platform.system() != 'Windows':
      # The Python zip utility does not preserve executable permissions, but
      # this does not seem to be a problem for Windows, which does not have a
      # built in zip utility. :-/
      result, out = ExecuteCommand('unzip', temp_zip, '-d', temp_dir)
      if result != 0:
        raise Exception('Execution of "unzip %s -d %s" failed: %s' %
                        (temp_zip, temp_dir, str(out)))
      unzipped_dir = temp_dir + '/' + os.path.basename(latest)[:-len('.zip')]
    else:
      z = zipfile.ZipFile(temp_zip)
      z.extractall(temp_dir)
      unzipped_dir = os.path.join(temp_dir,
                                  os.path.basename(latest)[:-len('.zip')])
      z.close()
    if directory == SDK_DIR:
      unzipped_dir = os.path.join(temp_dir, 'dart-sdk')
    if os.path.exists(directory):
      print 'Removing old %s tree %s' % (name, directory)
      shutil.rmtree(directory)
      if os.path.exists(directory):
        raise Exception(
          'Removal of directory %s failed. Is the executable running?' %
          directory)
    shutil.move(unzipped_dir, directory)
  finally:
    shutil.rmtree(temp_dir)

  # create the version stamp
  v = open(version_file, 'w')
  v.write(latest)
  v.close()

  print 'Successfully downloaded to %s' % directory
  return 0


def TooEarlyError():
  """Quick shortcutting function, to return early if someone requests a revision
  that is smaller than the earliest stored. This saves us from doing repeated
  requests until we get down to 0."""
  print ('Unable to download requested revision because it is earlier than the '
      'earliest revision stored.')
  sys.exit(1)


def CopyDrtFont(drt_dir):
  if platform.system() != 'Windows':
    return
  shutil.copy('third_party/drt_resources/AHEM____.TTF', drt_dir)


def main():
  parser = optparse.OptionParser(usage='usage: %prog [options] download_name')
  parser.add_option('-r', '--revision', dest='revision',
                    help='Desired revision number to retrieve for the SDK. If '
                    'unspecified, retrieve the latest SDK build.',
                    action='store', default=None)
  parser.add_option('-d', '--debug', dest='debug',
                    help='Download a debug archive instead of a release.',
                    action='store_true', default=False)
  args, positional = parser.parse_args()

  if args.revision and int(args.revision) < LAST_VALID[positional[0]]:
    return TooEarlyError()

  # Use the incremental release bot ('dartium-*-inc-be') by default.
  # Issue 13399 Quick fix, update with channel support.
  bot = 'inc-be'
  if args.debug:
    print >>sys.stderr, (
      'Debug versions of Dartium and content_shell not available')
    return 1

  if positional[0] == 'dartium':
    GetDartiumRevision('Dartium', bot, DARTIUM_DIR, DARTIUM_VERSION,
                         DARTIUM_LATEST_PATTERN, DARTIUM_PERMANENT_PATTERN,
                         args.revision)
  elif positional[0] == 'sdk':
    GetSdkRevision('sdk', SDK_DIR, SDK_VERSION, SDK_LATEST_PATTERN,
        SDK_PERMANENT, args.revision)
  elif positional[0] == 'drt':
    GetDartiumRevision('content_shell', bot, DRT_DIR, DRT_VERSION,
                         DRT_LATEST_PATTERN, DRT_PERMANENT_PATTERN,
                         args.revision)
    CopyDrtFont(DRT_DIR)
  else:
    print ('Please specify the target you wish to download from Google Storage '
        '("drt", "dartium", "chromedriver", or "sdk")')

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