#!/usr/bin/env python
#
# Copyright 2019 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


################################################################################
#                                  API                                         #
################################################################################


def MakeCobaltArchiveFromFileList(output_archive_path,
                                  input_file_list,  # class FileList
                                  platform_name,
                                  platform_sdk_version,
                                  config,
                                  additional_buildinfo_dict={}):
  additional_buildinfo_dict = dict(additional_buildinfo_dict)
  b = Bundler(archive_zip_path=output_archive_path)
  b.MakeArchive(platform_name=platform_name,
                platform_sdk_version=platform_sdk_version,
                config=config,
                file_list=input_file_list,
                additional_buildinfo_dict=additional_buildinfo_dict)


def MakeCobaltArchiveFromSource(output_archive_path,
                                platform_name,
                                config,
                                platform_sdk_version,
                                additional_buildinfo_dict={},
                                include_black_box_tests=False):
  """ Returns None, failure is signaled via exception. """
  additional_buildinfo_dict = dict(additional_buildinfo_dict)
  _MakeCobaltArchiveFromSource(
      output_archive_path=output_archive_path,
      platform_name=platform_name,
      config=config,
      platform_sdk_version=platform_sdk_version,
      additional_buildinfo_dict=additional_buildinfo_dict,
      include_black_box_tests=include_black_box_tests)


def ExtractCobaltArchive(input_zip_path, output_directory_path, outstream=None):
  """Returns True if the extract operation was successfull."""
  b = Bundler(archive_zip_path=input_zip_path)
  return b.ExtractTo(output_dir=output_directory_path, outstream=outstream)


def ReadCobaltArchiveInfo(input_zip_path):
  b = Bundler(archive_zip_path=input_zip_path)
  return b.ReadMetaData()


################################################################################
#                                 IMPL                                         #
################################################################################


import argparse
import hashlib
import json
import md5
import os
import random
import shutil
import subprocess
import sys
import tempfile
import time
import traceback
import zipfile

from sets import Set

import _env

from starboard.build.port_symlink \
    import IsSymLink, IsWindows, MakeSymLink, ReadSymLink, Rmtree, OsWalk

from starboard.tools.app_launcher_packager import CopyAppLauncherTools
from starboard.tools.paths import BuildOutputDirectory, REPOSITORY_ROOT

from starboard.build.filelist import \
    FileList, GetFileType, TempFileSystem, \
    TYPE_NONE, TYPE_SYMLINK_DIR, TYPE_DIRECTORY, TYPE_FILE

from starboard.build.port_symlink import Rmtree
from starboard.tools.build import GetPlatformConfig
from starboard.tools.config import GetAll as GetAllConfigs
from starboard.tools.platform import GetAll as GetAllPlatforms


# Source resource paths.
_SELF_DIR = os.path.abspath(os.path.dirname(__file__))
_SRC_CONTENT_PATH = os.path.join(_SELF_DIR, 'cobalt_archive_content')


# Relative paths from the resulting archive root. The path seperator
# is normalized to '/'.
_OUT_ARCHIVE_ROOT = '__cobalt_archive'
_OUT_FINALIZE_DECOMPRESSION_PATH = '%s/%s' % (_OUT_ARCHIVE_ROOT,
                                             'finalize_decompression')
_OUT_METADATA_PATH = '%s/%s' % (_OUT_ARCHIVE_ROOT, 'metadata.json')
_OUT_DECOMP_PY = '%s/%s' % (_OUT_FINALIZE_DECOMPRESSION_PATH,
                           'decompress.py')
_OUT_DECOMP_JSON = '%s/%s' % (_OUT_FINALIZE_DECOMPRESSION_PATH,
                             'decompress.json')


class Bundler:
  """Bundler is a utility for managing device bundles of codes. It is
  used for creating the zip file and also unzipping."""
  def __init__(self, archive_zip_path):
    self.archive_zip_path = archive_zip_path

  def ExtractTo(self, output_dir, outstream=None):
    """Returns True if all files were extracted, False otherwise."""
    outstream = outstream if outstream else sys.stdout
    assert(os.path.exists(self.archive_zip_path))
    print('UNZIPPING ' + self.archive_zip_path + ' -> ' + output_dir)
    ok = _ExtractFiles(self.archive_zip_path, output_dir, outstream)
    # Now that all files have been extracted, execute the final decompress
    # step.
    decomp_py = os.path.abspath(os.path.join(output_dir, _OUT_DECOMP_PY))
    assert(os.path.isfile(decomp_py)), decomp_py
    cmd_str = 'python ' + decomp_py
    outstream.write('Executing: %s\n' % cmd_str)
    rc = subprocess.call(cmd_str, shell=True, stdout=outstream,
                         stderr=outstream)
    ok &= rc is 0
    return ok

  def ReadMetaData(self):
    with zipfile.ZipFile(self.archive_zip_path, 'r', allowZip64=True) as zf:
      json_str = zf.read(_OUT_METADATA_PATH)
    return json.loads(json_str)

  def MakeArchive(self,
                  platform_name,
                  platform_sdk_version,
                  config,
                  file_list,  # class FileList
                  additional_buildinfo_dict={}):
    if not config in GetAllConfigs():
      raise ValueError('Expected %s to be one of %s'
                       % (config, GetAllConfigs()))
    additional_buildinfo_dict = dict(additional_buildinfo_dict)  # Copy
    build_info_str = _GenerateBuildInfoStr(
        platform_name=platform_name,
        platform_sdk_version=platform_sdk_version,
        config=config,
        additional_buildinfo_dict=additional_buildinfo_dict)
    with zipfile.ZipFile(self.archive_zip_path, mode='w',
                         compression=zipfile.ZIP_DEFLATED,
                         allowZip64=True) as zf:
      # Copy the cobalt_archive_content directory into the root of the archive.
      content_file_list = FileList()
      content_file_list.AddAllFilesInPath(root_dir=_SRC_CONTENT_PATH,
                                          sub_dir=_SRC_CONTENT_PATH)
      for file_path, archive_path in content_file_list.file_list:
        print file_path, archive_path
        zf.write(file_path, arcname=archive_path)
      # Write out the metadata.
      zf.writestr(_OUT_METADATA_PATH, build_info_str)
      # TODO: Remove line below after device server has been updated and
      # restarted.
      zf.writestr('deploy_info.json', build_info_str)
      if file_list.file_list:
        print('  Compressing ' + str(len(file_list.file_list)) + ' files')
      for file_path, archive_path in file_list.file_list:
        # TODO: Use and implement _FoldIdenticalFiles() to reduce duplicate
        # files. This will help platforms like nxswitch which include a lot
        # of duplicate files for the sdk.
        zf.write(file_path, arcname=archive_path)
      if file_list.symlink_dir_list:
        print('  Compressing ' + str(len(file_list.symlink_dir_list)) + ' symlinks')
      # Generate the decompress.json file used by decompress.py.
      # Removes the first element which is the root directory, which is not
      # important for symlink creation.
      symlink_dir_list = [l[1:] for l in file_list.symlink_dir_list]
      # Replace '\\' with '/'
      symlink_dir_list = [_ToUnixPaths(l) for l in symlink_dir_list]
      decompress_json_str = _JsonDumpPrettyPrint({
        'symlink_dir': symlink_dir_list,
        'symlink_dir_doc': '[link_dir_path, target_dir_path]'
      })
      zf.writestr(_OUT_DECOMP_JSON, decompress_json_str)


def _ToUnixPaths(path_list):
  out = []
  for p in path_list:
    out.append(p.replace('\\', '/'))
  return out


def _JsonDumpPrettyPrint(data):
  return json.dumps(data, sort_keys=True, indent=4, separators=(',', ': '))


def _CheckChildPathIsUnderParentPath(child_path, parent_path):
  parent_path = os.path.join(
      os.path.realpath(parent_path), '')
  f = os.path.realpath(child_path)
  common_prefix = os.path.commonprefix([child_path, parent_path])
  if common_prefix != parent_path:
    raise ValueError('Bundle files MUST be located under ' + \
                       parent_path + ', BadFile = ' + f)


def _MakeDirs(path):
  if not os.path.isdir(path):
    os.makedirs(path)


def _FindPossibleDeployDirs(build_root):
  out = []
  root_dirs = os.listdir(build_root)
  for d in root_dirs:
    if d in ('gen', 'gypfiles', 'obj', 'obj.host'):
      continue
    d = os.path.join(build_root, d)
    if os.path.isfile(d):
      continue
    if IsSymLink(d):
      continue
    out.append(os.path.normpath(d))
  return out


def _GetDeployDirs(platform_name, config):
  try:
    gyp_config = GetPlatformConfig(platform_name)
    return gyp_config.GetDeployDirs()
  except NotImplementedError:
    # TODO: Investigate why Logging.info(...) eats messages even when
    # the logging module is set to logging level INFO or DEBUG and when
    # this is fixed then replace the print functions in this file with logging.
    print('\n********************************************************\n'
          '%s: specific deploy directories not found, auto \n'
          'including possible deploy directories from build root.'
          '\n********************************************************\n'
          % __file__)
    build_root = BuildOutputDirectory(platform_name, config)
    return _FindPossibleDeployDirs(build_root)


def _MakeCobaltArchiveFromSource(output_archive_path,
                                 platform_name,
                                 config,
                                 platform_sdk_version,
                                 additional_buildinfo_dict,
                                 include_black_box_tests):
  _MakeDirs(os.path.dirname(output_archive_path))
  out_directory = BuildOutputDirectory(platform_name, config)
  root_dir = os.path.abspath(os.path.join(out_directory, '..', '..'))
  flist = FileList()
  inc_dirs = _GetDeployDirs(platform_name, config)
  print 'Adding binary files to bundle...'
  for path in inc_dirs:
    path = os.path.join(out_directory, path)
    if not os.path.exists(path):
      print 'Skipping deploy directory', path, 'because it does not exist.'
      continue
    print '  adding ' + os.path.abspath(path)
    flist.AddAllFilesInPath(root_dir=root_dir, sub_dir=path)
  print '...done'
  launcher_tools_path = os.path.join(
      os.path.dirname(output_archive_path),
      '____app_launcher')
  if os.path.exists(launcher_tools_path):
    Rmtree(launcher_tools_path)
  print ('Adding app_launcher_files to bundle in ' +
         os.path.abspath(launcher_tools_path))

  try:
    CopyAppLauncherTools(repo_root=REPOSITORY_ROOT,
                         dest_root=launcher_tools_path,
                         additional_glob_patterns=[],
                         include_black_box_tests=include_black_box_tests)
    flist.AddAllFilesInPath(root_dir=launcher_tools_path,
                            sub_dir=launcher_tools_path)
    print '...done'
    print 'Making cobalt archive...'
    MakeCobaltArchiveFromFileList(
        output_archive_path,
        input_file_list=flist,
        platform_name=platform_name,
        platform_sdk_version=platform_sdk_version,
        config=config,
        additional_buildinfo_dict=additional_buildinfo_dict)
    print '...done'
  finally:
    Rmtree(launcher_tools_path)


# TODO: Implement into bundler. This is unit tested at this time.
# Returns files_list, copy_list, where file_list is a list of physical
# files, and copy_list contains a 2-tuple of [physical_file, copy_location]
# that describes which files should be copied.
# Example:
#  files, copy_list = _FoldIdenticalFiles(['in0/test.txt', 'in1/test.txt'])
#  Output:
#    files => ['in0/test.txt']
#    copy_list => ['in0/test.txt', 'in1/test.txt']
def _FoldIdenticalFiles(file_path_list):
  # Remove duplicates.
  file_path_list = list(Set(file_path_list))
  file_path_list.sort()
  def Md5File(fpath):
    hash_md5 = hashlib.md5()
    with open(fpath, 'rb') as f:
      for chunk in iter(lambda: f.read(4096), b''):
        hash_md5.update(chunk)
    return hash_md5.hexdigest()
  # Output
  phy_file_list = []
  copy_list = []
  # Temp data structure.
  file_map = {}
  for file_path in file_path_list:
    name = os.path.basename(file_path)
    fsize = os.stat(file_path).st_size
    entry = (name, fsize)
    files = file_map.get(entry, [])
    files.append(file_path)
    file_map[entry] = files
  for (fname, fsize), path_list in file_map.iteritems():
    assert(len(path_list))
    phy_file_list.append(path_list[0])
    if len(path_list) == 1:
      continue
    else:
      md5_dict = { Md5File(path_list[0]): path_list[0]  }
      for tail_file in path_list[1:]:
        new_md5 = Md5File(tail_file)
        matching_file = md5_dict.get(new_md5, None)
        if matching_file != None:
          # Match found.
          copy_list.append((matching_file, tail_file))
        else:
          phy_file_list.append(tail_file)
          md5_dict[new_md5] = tail_file
  return phy_file_list, copy_list


def _GenerateBuildInfoStr(platform_name, platform_sdk_version,
                          config, additional_buildinfo_dict):
  from time import gmtime, strftime
  build_info = dict(additional_buildinfo_dict)  # Copy dict.
  build_info['archive_time_RFC_2822'] = \
      strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
  build_info['archive_time_local'] = time.asctime()
  build_info['platform'] = platform_name
  build_info['config'] = config
  build_info['sdk_version'] = platform_sdk_version
  # Can be used by clients for caching reasons.
  build_info['random_uint64'] = random.randint(0, 0xffffffffffffffff)
  build_info_str = _JsonDumpPrettyPrint(build_info)
  return build_info_str


def _AddFilesAndSymlinksToZip(open_zipfile, archive_file_list):
  sym_links = []
  for path, archive_name in archive_file_list:
    if IsSymLink(path):
      sym_links.append([path, archive_name])
    else:
      open_zipfile.write(path, arcname=archive_name)
  for path, archive_name in sym_links:
    zinfo = zipfile.ZipInfo(path)
    link_path = ReadSymLink(path)
    zinfo.filename = rel_path
    zinfo.comment = json.dumps({'symlink': link_path})
    open_zipfile.writestr(zinfo, rel_path, compress_type=zipfile.ZIP_DEFLATED)


# Returns True if all files were extracted, else False.
def _ExtractFiles(input_zip_path, output_dir, outstream):
  all_ok = True
  with zipfile.ZipFile(input_zip_path, 'r', allowZip64=True) as zf:
    for zinfo in zf.infolist():
      try:
        zf.extract(zinfo, path=output_dir)
      except Exception as err:
        msg = 'Exception happend during bundle extraction: ' + str(err) + '\n'
        outstream.write(msg)
        all_ok = False
  return all_ok


################################################################################
#                              UNIT TEST                                       #
################################################################################


def _UnitTestBundler_ExtractTo():
  flist = FileList()
  tf = TempFileSystem()
  tf.Clear()
  tf.Make()
  flist.AddSymLink(tf.root_in_tmp, tf.sym_dir)
  bundle_zip = os.path.join(tf.root_tmp, 'bundle.zip')
  b = Bundler(bundle_zip)
  b.MakeArchive(platform_name='fake',
                platform_sdk_version='fake_sdk',
                config='devel',
                file_list=flist)
  out_dir = os.path.join(tf.root_tmp, 'out')
  b.ExtractTo(out_dir)
  out_from_dir = os.path.join(out_dir, 'from_dir')
  out_from_dir_lnk = os.path.join(out_dir, 'from_dir_lnk')
  assert(GetFileType(out_from_dir) == TYPE_DIRECTORY)
  assert(GetFileType(out_from_dir_lnk) == TYPE_SYMLINK_DIR)
  resolved_from_link_path = os.path.join(out_dir, ReadSymLink(out_from_dir_lnk))
  assert(os.path.abspath(out_from_dir) ==
         os.path.abspath(resolved_from_link_path))


def _UnitTestBundler_MakesDeployInfo():
  flist = FileList()
  tf = TempFileSystem()
  tf.Clear()
  tf.Make()
  bundle_zip = os.path.join(tf.root_tmp, 'bundle.zip')
  b = Bundler(bundle_zip)
  b.MakeArchive(platform_name='fake',
                platform_sdk_version='fake_sdk',
                config='devel',
                file_list=flist)
  out_dir = os.path.join(tf.root_tmp, 'out')
  b.ExtractTo(out_dir)
  out_metadata_file = os.path.join(out_dir, _OUT_METADATA_PATH)
  assert(GetFileType(out_metadata_file) == TYPE_FILE)
  with open(out_metadata_file) as fd:
    text = fd.read()
    js = json.loads(text)
    assert(js)
    assert(js['sdk_version'] == 'fake_sdk')
    assert(js['platform'] == 'fake')
    assert(js['config'] == 'devel')


def _UnitTest_FoldIdenticalFiles():
  tf_root = TempFileSystem('bundler_fold')
  tf_root.Clear()
  tf1 = TempFileSystem(os.path.join('bundler_fold', '1'))
  tf2 = TempFileSystem(os.path.join('bundler_fold', '2'))
  tf1.Make()
  tf2.Make()
  flist = FileList()
  subdirs = [tf1.root_in_tmp, tf2.root_in_tmp]
  flist.AddAllFilesInPaths(tf_root.root_tmp, subdirs)
  flist.Print()
  identical_files = [tf1.test_txt, tf2.test_txt]
  physical_files, copy_files = _FoldIdenticalFiles(identical_files)
  assert(tf1.test_txt == physical_files[0])
  assert(tf1.test_txt in copy_files[0][0])
  assert(tf2.test_txt in copy_files[0][1])


def _UnitTest():
  tests = [
    ['UnitTestBundler_ExtractTo', _UnitTestBundler_ExtractTo],
    ['UnitTestBundler_MakesDeployInfo', _UnitTestBundler_MakesDeployInfo],
    ['UnitTest_FoldIdenticalFiles', _UnitTest_FoldIdenticalFiles],
  ]
  failed_tests = []
  for name, test in tests:
    try:
      print('\n' + name + ' started.')
      test()
      print(name + ' passed.')
    except Exception as err:
      failed_tests.append(name)
      traceback.print_exc()
      print('Error happened during test ' + name)

  if failed_tests:
    print '\n\nThe following tests failed: ' + ','.join(failed_tests)
    return 1
  else:
    return 0


################################################################################
#                                CMD LINE                                      #
################################################################################


def _MakeCobaltPlatformArchive(platform, config, output_zip,
                               include_black_box_tests):
  if not platform:
    platform = raw_input('platform: ')
  if not platform in GetAllPlatforms():
    raise ValueError('Platform "%s" not recognized, expected one of: \n%s'
                     % (platform, GetAllPlatforms()))
  if not config:
    config = raw_input('config: ')
  if not output_zip:
    output_zip = raw_input('output_zip: ')
  if not output_zip.endswith('.zip'):
    output_zip += '.zip'
  start_time = time.time()
  MakeCobaltArchiveFromSource(
      output_zip,
      platform,
      config,
      platform_sdk_version='TEST',
      additional_buildinfo_dict={},
      include_black_box_tests=include_black_box_tests)
  time_delta = time.time() - start_time
  if not os.path.isfile(output_zip):
    raise ValueError('Expected zip file at ' + output_zip)
  print '\nGenerated: %s in %d seconds' % (output_zip, int(time_delta))

# Returns True/False
def _DecompressArchive(in_zip, out_path):
  if not in_zip:
    in_zip = raw_input('cobalt archive path: ')
  if not out_path:
    out_path = raw_input('output path: ')
  return ExtractCobaltArchive(input_zip_path=in_zip,
                              output_directory_path=out_path)


def _main():
  # Create a private parser that will print the full help whenever the command
  # line fails to fully parse.
  class MyParser(argparse.ArgumentParser):
    def error(self, message):
      sys.stderr.write('error: %s\n' % message)
      self.print_help()
      sys.exit(2)
  help_msg = (
    'Example 1:\n'
    '  python cobalt_archive.py --create --platform nxswitch'
    ' --config devel --out_path <OUT_ZIP>\n\n'
    'Example 2:\n'
    '  python cobalt_archive.py --extract --in_path <ARCHIVE_PATH.ZIP>'
    ' --out_path <OUT_DIR>')
  # Enables new lines in the description and epilog.
  formatter_class = argparse.RawDescriptionHelpFormatter
  parser = MyParser(epilog=help_msg, formatter_class=formatter_class)
  group = parser.add_mutually_exclusive_group(required=True)
  group.add_argument(
      '-u',
      '--unit_test',
      help='Run cobalt archive UnitTest',
      action='store_true')
  group.add_argument(
      '-c',
      '--create',
      help='Creates an archive from source directory, optional arguments'
           ' include --platform --config and --out_path',
      action='store_true')
  group.add_argument(
      '-x',
      '--extract',
      help='Extract archive from IN_PATH to OUT_PATH, optional arguments '
           'include --in_path and --out_path',
      action='store_true')
  parser.add_argument('--platform', type=str,
                      help='Optional, used for --create',
                      default=None)
  parser.add_argument('--config', type=str,
                      help='Optional, used for --create',
                      choices=GetAllConfigs(),
                      default=None)
  parser.add_argument('--out_path', type=str,
                      help='Optional, used for --create and --decompress',
                      default=None)
  parser.add_argument('--in_path', type=str,
                      help='Optional, used for decompress',
                      default=None)
  parser.add_argument('--include_black_box_tests',
                      help='Optional, used for --create to add blackbox tests',
                      action='store_true')
  args = parser.parse_args()
  if args.unit_test:
    sys.exit(_UnitTest())
  elif args.create:
    _MakeCobaltPlatformArchive(
        platform=args.platform,
        config=args.config,
        output_zip=args.out_path,
        include_black_box_tests=args.include_black_box_tests)
    sys.exit(0)
  elif args.extract:
    ok = _DecompressArchive(args.in_path, args.out_path)
    rc = 0 if ok else 1
    sys.exit(rc)
  else:
    parser.print_help()


if __name__ == '__main__':
  _main()
