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

"""Tool to roll Chromium into Mojo. See:
https://github.com/domokit/mojo/wiki/Rolling-code-between-chromium-and-mojo#chromium---mojo-updates
"""

import argparse
import glob
import itertools
import os
import subprocess
import sys
import tempfile
import time
import zipfile

import mopy.gn as gn
from mopy.config import Config
from mopy.paths import Paths
from mopy.version import Version

sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
                             "third_party", "pyelftools"))
import elftools.elf.elffile as elffile

sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir,
                             'devtools', 'common'))
import android_gdb.signatures as signatures


BLACKLISTED_APPS = [
  # The network service apps are not produced out of the Mojo repo, but may
  # be present in the build dir.
  "network_service.mojo",
  "network_service_apptests.mojo",
]


def target(config):
  target_name = config.target_os + "-" + config.target_cpu
  if config.is_official_build:
    target_name += "-official"
  return target_name


def find_apps_to_upload(build_dir):
  apps = []
  for path in glob.glob(build_dir + "/*"):
    if not os.path.isfile(path):
      continue
    _, ext = os.path.splitext(path)
    if ext != '.mojo':
      continue
    if os.path.basename(path) in BLACKLISTED_APPS:
      continue
    apps.append(path)
  return apps


def check_call(command_line, dry_run, **kwargs):
  if dry_run:
    print command_line
  else:
    subprocess.check_call(command_line, **kwargs)


def upload(config, source, dest, dry_run, gzip=False):
  paths = Paths(config)
  sys.path.insert(0, os.path.join(paths.src_root, "tools"))
  # pylint: disable=F0401
  import find_depot_tools

  depot_tools_path = find_depot_tools.add_depot_tools_to_path()
  gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")

  command_line = [gsutil_exe, "cp"]
  if gzip and "." in source:
    extension = source.split(".")[-1]
    command_line.extend(["-z", extension])
  command_line.extend([source, dest])

  check_call(command_line, dry_run)


def upload_symbols(config, build_dir, breakpad_upload_urls, dry_run):
  dump_syms_exe = os.path.join(Paths().src_root,
                               "mojo", "tools", "linux64", "dump_syms")
  symupload_exe = os.path.join(Paths().src_root,
                               "mojo", "tools", "linux64", "symupload")
  dest_dir = "gs://mojo/symbols/"
  symbols_dir = os.path.join(build_dir, "symbols")
  with open(os.devnull, "w") as devnull:
    for name in os.listdir(symbols_dir):
      path = os.path.join(symbols_dir, name)
      with open(path) as f:
        signature = signatures.get_signature(f, elffile)
        if signature is not None:
          dest = dest_dir + signature
          upload(config, path, dest, dry_run)
      if breakpad_upload_urls:
        with tempfile.NamedTemporaryFile() as temp:
          check_call([dump_syms_exe, path], dry_run,
                     stdout=temp, stderr=devnull)
          temp.flush()
          for upload_url in breakpad_upload_urls:
            check_call([symupload_exe, temp.name, upload_url], dry_run)

def upload_shell(config, dry_run, verbose):
  paths = Paths(config)
  zipfile_name = target(config)
  version = Version().version

  # Upload the binary.
  # TODO(blundell): Change this to be in the same structure as the LATEST files,
  # e.g., gs://mojo/shell/linux-x64/<version>/shell.zip.
  dest = "gs://mojo/shell/" + version + "/" + zipfile_name + ".zip"
  with tempfile.NamedTemporaryFile() as zip_file:
    with zipfile.ZipFile(zip_file, 'w') as z:
      shell_path = paths.target_mojo_shell_path
      with open(shell_path) as shell_binary:
        shell_filename = os.path.basename(shell_path)
        zipinfo = zipfile.ZipInfo(shell_filename)
        zipinfo.external_attr = 0777 << 16L
        compress_type = zipfile.ZIP_DEFLATED
        if config.target_os == Config.OS_ANDROID:
          # The APK is already compressed.
          compress_type = zipfile.ZIP_STORED
        zipinfo.compress_type = compress_type
        zipinfo.date_time = time.gmtime(os.path.getmtime(shell_path))
        if verbose:
          print "zipping %s" % shell_path
        z.writestr(zipinfo, shell_binary.read())
    upload(config, zip_file.name, dest, dry_run, gzip=False)

  # Update the LATEST file to contain the version of the new binary.
  latest_file = "gs://mojo/shell/%s/LATEST" % target(config)
  write_file_to_gs(version, latest_file, config, dry_run)


def upload_dart_snapshotter(config, dry_run, verbose):
  # Only built for Linux and Mac.
  if not config.target_os in [Config.OS_LINUX, Config.OS_MAC]:
    return

  paths = Paths(config)
  zipfile_name = target(config)
  version = Version().version

  dest = "gs://mojo/dart_snapshotter/" + version + "/" + zipfile_name + ".zip"
  with tempfile.NamedTemporaryFile() as zip_file:
    with zipfile.ZipFile(zip_file, 'w') as z:
      dart_snapshotter_path = paths.target_dart_snapshotter_path
      with open(dart_snapshotter_path) as dart_snapshotter_binary:
        dart_snapshotter_filename = os.path.basename(dart_snapshotter_path)
        zipinfo = zipfile.ZipInfo(dart_snapshotter_filename)
        zipinfo.external_attr = 0777 << 16L
        compress_type = zipfile.ZIP_DEFLATED
        zipinfo.compress_type = compress_type
        zipinfo.date_time = time.gmtime(os.path.getmtime(dart_snapshotter_path))
        if verbose:
          print "zipping %s" % dart_snapshotter_path
        z.writestr(zipinfo, dart_snapshotter_binary.read())
    upload(config, zip_file.name, dest, dry_run, gzip=False)

  # Update the LATEST file to contain the version of the new binary.
  latest_file = "gs://mojo/dart_snapshotter/%s/LATEST" % target(config)
  write_file_to_gs(version, latest_file, config, dry_run)


def upload_app(app_binary_path, config, dry_run):
  app_binary_name = os.path.basename(app_binary_path)
  version = Version().version
  gsutil_app_location = ("gs://mojo/services/%s/%s/%s" %
                         (target(config), version, app_binary_name))

  # Upload the new binary.
  upload(config, app_binary_path, gsutil_app_location, dry_run)


def upload_system_thunks_lib(config, dry_run):
  paths = Paths(config)
  version = Version().version
  dest = ("gs://mojo/system_thunks/%s/%s/libsystem_thunks.a" %
      (target(config), version))
  source_path = paths.build_dir + "/obj/mojo/libsystem_thunks.a"
  upload(config, source_path, dest, dry_run)


def write_file_to_gs(file_contents, dest, config, dry_run):
  with tempfile.NamedTemporaryFile() as temp_version_file:
    temp_version_file.write(file_contents)
    temp_version_file.flush()
    upload(config, temp_version_file.name, dest, dry_run)


def main():
  parser = argparse.ArgumentParser(description="Upload binaries for apps and "
      "the Mojo shell to google storage (by default on Linux, but this can be "
      "changed via options).")
  parser.add_argument("-n", "--dry_run", help="Dry run, do not actually "+
      "upload", action="store_true")
  parser.add_argument("-v", "--verbose", help="Verbose mode",
      action="store_true")
  parser.add_argument("--android",
                      action="store_true",
                      help="Upload the shell and apps for Android")
  parser.add_argument("--official",
                      action="store_true",
                      help="Upload the official build of the Android shell")
  parser.add_argument("--symbols-upload-url",
                      action="append", default=[],
                      help="URL of the server to upload breakpad symbols to")
  args = parser.parse_args()

  is_official_build = args.official
  target_os = Config.OS_LINUX
  if args.android:
    target_os = Config.OS_ANDROID
  elif is_official_build:
    print "Uploading official builds is only supported for android."
    return 1

  config = Config(target_os=target_os, is_debug=False,
                  is_official_build=is_official_build)

  upload_shell(config, args.dry_run, args.verbose)

  if is_official_build:
    print "Skipping uploading apps (official apk build)."
    return 0

  build_directory = gn.BuildDirectoryForConfig(config, Paths(config).src_root)
  apps_to_upload = find_apps_to_upload(build_directory)
  for app in apps_to_upload:
    upload_app(app, config, args.dry_run)

  upload_symbols(config, build_directory,
                 args.symbols_upload_url, args.dry_run)

  upload_dart_snapshotter(config, args.dry_run, args.verbose)

  upload_system_thunks_lib(config, args.dry_run)

  return 0

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