#!/usr/bin/env python
#
# Copyright (c) 2013, 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.

import imp
import optparse
import os
import subprocess
import sys

DART_DIR = os.path.dirname(os.path.dirname(__file__))
GSUTIL = os.path.join(DART_DIR, 'third_party', 'gsutil', 'gsutil')
BOT_UTILS = os.path.join(DART_DIR, 'tools', 'bots', 'bot_utils.py')
BASENAME_PATTERN = 'darteditor-%(system)s-%(bits)s'
FILENAME_PATTERN = BASENAME_PATTERN + '.zip'

DRY_RUN = False

bot_utils = imp.load_source('bot_utils', BOT_UTILS)

class ChangedWorkingDirectory(object):
  def __init__(self, working_directory):
    self._working_directory = working_directory

  def __enter__(self):
    self._old_cwd = os.getcwd()
    print "Enter directory = ", self._working_directory
    if not DRY_RUN:
      os.chdir(self._working_directory)

  def __exit__(self, *_):
    print "Enter directory = ", self._old_cwd
    os.chdir(self._old_cwd)

def GetOptionsParser():
  parser = optparse.OptionParser("usage: %prog [options]")
  parser.add_option("--scratch-dir",
                    help="Scratch directory to use.")
  parser.add_option("--revision", type="int",
                    help="Revision we want to sign.")
  parser.add_option("--channel", type="string",
                    default=None,
                    help="Channel we want to sign.")
  parser.add_option("--dry-run", action="store_true", dest="dry_run",
                    default=False,
                    help="Do a dry run and do not execute any commands.")
  parser.add_option("--prepare", action="store_true", dest="prepare",
                    default=False,
                    help="Prepare the .exe/.zip files to sign.")
  parser.add_option("--deploy", action="store_true", dest="deploy",
                    default=False,
                    help="Pack the signed .exe/.zip files and deploy.")
  return parser

def die(msg, withOptions=True):
  print msg
  if withOptions:
    GetOptionsParser().print_usage()
  sys.exit(1)

def run(command):
  """We use run() instead of builtin python methods, because not all
  functionality can easily be done by python and we can support --dry-run"""

  print "Running: ", command
  if not DRY_RUN:
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    (stdout, stderr) = process.communicate()
    if process.returncode != 0:
      print "DEBUG: failed to run command '%s'" % command
      print "DEBUG: stdout = ", stdout
      print "DEBUG: stderr = ", stderr
      print "DEBUG: returncode = ", process.returncode
      raise OSError(process.returncode)

def clean_directory(directory):
  if os.path.exists(directory):
    run(['rm', '-r', directory])
  run(['mkdir', '-p', directory])

def rm_tree(directory):
  if os.path.exists(directory):
    run(['rm', '-r', directory])

def copy_tree(from_dir, to_dir):
  if os.path.exists(to_dir):
    run(['rm', '-r', to_dir])
  run(['cp', '-Rp', from_dir, to_dir])

def copy_file(from_file, to_file):
  if os.path.exists(to_file):
    run(['rm', to_file])
  run(['cp', '-p', from_file, to_file])

def copy_and_zip(from_dir, to_dir):
  rm_tree(to_dir)
  copy_tree(from_dir, to_dir)

  dirname = os.path.basename(to_dir)
  with ChangedWorkingDirectory(os.path.dirname(to_dir)):
    run(['zip', '-r9', dirname + '.zip', dirname])

def unzip_and_copy(extracted_zipfiledir, to_dir):
  rm_tree(extracted_zipfiledir)
  run(['unzip', extracted_zipfiledir + '.zip', '-d',
       os.path.dirname(extracted_zipfiledir)])
  rm_tree(to_dir)
  copy_tree(extracted_zipfiledir, to_dir)

def download_from_new_location(channel, config, destination):
  namer = bot_utils.GCSNamer(channel,
                             bot_utils.ReleaseType.RAW)
  bucket = namer.editor_zipfilepath(config['revision'], config['system'],
                                    config['bits'])
  run([GSUTIL, 'cp', bucket, destination])

def download_msi_installer_from_new_location(channel, config, destination):
  namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RAW)
  bucket = namer.editor_installer_filepath(
      config['revision'], config['system'], config['bits'], 'msi')
  run([GSUTIL, 'cp', bucket, destination])

def upload_to_new_location(channel, config, source_zip):
  namer = bot_utils.GCSNamer(channel,
                             bot_utils.ReleaseType.SIGNED)
  zipfilename = namer.editor_zipfilename(config['system'], config['bits'])
  bucket = namer.editor_zipfilepath(config['revision'], config['system'],
                                    config['bits'])

  if not DRY_RUN:
    bot_utils.CreateChecksumFile(source_zip, mangled_filename=zipfilename)
  md5_zip_file = source_zip + '.md5sum'

  run([GSUTIL, 'cp', source_zip, bucket])
  run([GSUTIL, 'cp', md5_zip_file, bucket + '.md5sum'])
  run([GSUTIL, 'setacl', 'public-read', bucket])
  run([GSUTIL, 'setacl', 'public-read', bucket + '.md5sum'])

def upload_msi_installer_to_new_location(channel, config, signed_msi):
  namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.SIGNED)
  bucket = namer.editor_installer_filepath(
      config['revision'], config['system'], config['bits'], 'msi')
  run([GSUTIL, 'cp', '-a', 'public-read', signed_msi, bucket])

def main():
  if sys.platform != 'linux2':
    print "This script was only tested on linux. Please run it on linux!"
    sys.exit(1)

  parser = GetOptionsParser()
  (options, args) = parser.parse_args()

  if not options.scratch_dir:
    die("No scratch directory given.")
  if not options.revision:
    die("No revision given.")
  if not options.prepare and not options.deploy:
    die("No prepare/deploy parameter given.")
  if options.prepare and options.deploy:
    die("Can't have prepare and deploy parameters at the same time.")
  if len(args) > 0:
    die("Invalid additional arguments: %s." % args)

  if not options.channel:
    die("You need to specify a channel with --channel.")

  global DRY_RUN
  DRY_RUN = options.dry_run

  downloads_dir = os.path.join(options.scratch_dir, 'downloads')
  presign_dir = os.path.join(options.scratch_dir, 'presign')
  postsign_dir = os.path.join(options.scratch_dir, 'postsign')
  uploads_dir = os.path.join(options.scratch_dir, 'uploads')

  if options.prepare:
    # Clean all directories
    clean_directory(downloads_dir)
    clean_directory(presign_dir)
    clean_directory(postsign_dir)
    clean_directory(uploads_dir)
  elif options.deploy:
    clean_directory(uploads_dir)

  # These are the locations where we can find the *.app folders and *.exe files
  # and the names we use inside the scratch directory.
  locations = {
    'macos' : {
      'editor' : os.path.join('dart', 'DartEditor.app'),
      'chrome' : os.path.join('dart', 'chromium', 'Chromium.app'),

      'editor_scratch' : 'DartEditor%(bits)s.app',
      'chrome_scratch' : 'Chromium%(bits)s.app',

      'zip' : True,
    },
    'win32' : {
      'editor' : os.path.join('dart', 'DartEditor.exe'),
      'chrome' : os.path.join('dart', 'chromium', 'chrome.exe'),

      'msi_scratch' : 'darteditor-installer-windows-%(bits)s.msi',
      'editor_scratch' : 'DartEditor%(bits)s.exe',
      'chrome_scratch' : 'chromium%(bits)s.exe',

      'zip' : False,
    },
  }

  # Desitination of zip files we download
  for system in ('macos', 'win32'):
    for bits in ('32', '64'):
      config = {
        'revision' : options.revision,
        'system' : system,
        'bits' : bits,
      }

      destination = os.path.join(downloads_dir, FILENAME_PATTERN % config)
      destination_dir = os.path.join(downloads_dir, BASENAME_PATTERN % config)

      deploy = os.path.join(uploads_dir, FILENAME_PATTERN % config)
      deploy_dir = os.path.join(uploads_dir, BASENAME_PATTERN % config)

      if options.prepare:
        # Download *.zip files from GCS buckets
        download_from_new_location(options.channel, config, destination)

        run(['unzip', destination, '-d', destination_dir])

        for name in ['editor', 'chrome']:
          from_path = os.path.join(destination_dir, locations[system][name])
          to_path = os.path.join(
              presign_dir, locations[system]['%s_scratch' % name] % config)

          if locations[system]['zip']:
            # We copy a .app directory directory and zip it
            copy_and_zip(from_path, to_path)
          else:
            # We copy an .exe file
            copy_file(from_path, to_path)

        # Download .*msi installer from GCS to presign directory
        if system == 'win32':
          presign_msi = os.path.join(
              presign_dir, locations[system]['msi_scratch'] % config)
          download_msi_installer_from_new_location(
              options.channel, config, presign_msi)
      elif options.deploy:
        copy_tree(destination_dir, deploy_dir)

        for name in ['editor', 'chrome']:
          from_path = os.path.join(
              postsign_dir, locations[system]['%s_scratch' % name] % config)
          to_path = os.path.join(deploy_dir, locations[system][name])

          if locations[system]['zip']:
            # We unzip a zip file and copy the resulting signed .app directory
            unzip_and_copy(from_path, to_path)
          else:
            # We copy the signed .exe file
            copy_file(from_path, to_path)

        deploy_zip_file = os.path.abspath(deploy)
        with ChangedWorkingDirectory(deploy_dir):
          run(['zip', '-r9', deploy_zip_file, 'dart'])

        # Upload *.zip/*.zip.md5sum and set 'public-read' ACL
        upload_to_new_location(options.channel, config, deploy_zip_file)

        # Upload *.msi installer and set 'public-read ACL
        if system == 'win32':
          postsign_msi = os.path.join(
              postsign_dir, locations[system]['msi_scratch'] % config)
          upload_msi_installer_to_new_location(
              options.channel, config, postsign_msi)

if __name__ == '__main__':
  main()

