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

import argparse
import json
import os
import re
import sys

if sys.version_info < (2, 7, 0):
  sys.stderr.write("python 2.7 or later is required run this script\n")
  sys.exit(1)

import buildbot_common
import build_projects
import build_version
import easy_template
import parse_dsc

from build_paths import SDK_SRC_DIR, OUT_DIR, SDK_RESOURCE_DIR

sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
import getos
import oshelpers


def RemoveBuildCruft(outdir):
  for root, _, files in os.walk(outdir):
    for f in files:
      path = os.path.join(root, f)
      ext = os.path.splitext(path)[1]
      # Remove unwanted files from the package. Also remove manifest.json files
      # (which we usually want). These ones are the manifests of the invidual
      # examples, though, which CWS complains about. The master manifest.json
      # is generated after we call RemoveBuildCruft.
      if (ext in ('.d', '.o') or
          f == 'dir.stamp' or
          f == 'manifest.json' or
          re.search(r'_unstripped_.*?\.nexe', f)):
        buildbot_common.RemoveFile(path)


def StripNexes(outdir, platform, pepperdir):
  for root, _, files in os.walk(outdir):
    for f in files:
      path = os.path.join(root, f)
      m = re.search(r'lib(32|64).*\.so', path)
      arch = None
      if m:
        # System .so file. Must be x86, because ARM doesn't support glibc yet.
        arch = 'x86_' + m.group(1)
      else:
        basename, ext = os.path.splitext(f)
        if ext in ('.nexe', '.so'):
          # We can get the arch from the filename...
          valid_arches = ('x86_64', 'x86_32', 'arm')
          for a in valid_arches:
            if basename.endswith(a):
              arch = a
              break
      if not arch:
        continue

      strip = GetStrip(pepperdir, platform, arch, 'newlib')
      buildbot_common.Run([strip, path])


def GetStrip(pepperdir, platform, arch, toolchain):
  base_arch = {'x86_32': 'x86', 'x86_64': 'x86', 'arm': 'arm'}[arch]
  bin_dir = os.path.join(pepperdir, 'toolchain',
                         '%s_%s_%s' % (platform, base_arch, toolchain), 'bin')
  strip_prefix = {'x86_32': 'i686', 'x86_64': 'x86_64', 'arm': 'arm'}[arch]
  strip_name = '%s-nacl-strip' % strip_prefix
  return os.path.join(bin_dir, strip_name)


def main(args):
  parser = argparse.ArgumentParser()
  parser.add_argument('-c', '--channel',
      help='Channel to display in the name of the package.')

  # To setup bash completion for this command first install optcomplete
  # and then add this line to your .bashrc:
  #  complete -F _optcomplete build_app.py
  try:
    import optcomplete
    optcomplete.autocomplete(parser)
  except ImportError:
    pass

  options = parser.parse_args(args)

  if options.channel:
    if options.channel not in ('Dev', 'Beta'):
      parser.error('Unknown channel: %s' % options.channel)

  toolchains = ['newlib', 'glibc']

  pepper_ver = str(int(build_version.ChromeMajorVersion()))
  pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver)
  app_dir = os.path.join(OUT_DIR, 'naclsdk_app')
  app_examples_dir = os.path.join(app_dir, 'examples')
  sdk_resources_dir = SDK_RESOURCE_DIR
  platform = getos.GetPlatform()

  buildbot_common.RemoveDir(app_dir)
  buildbot_common.MakeDir(app_dir)

  # Add some dummy directories so build_projects doesn't complain...
  buildbot_common.MakeDir(os.path.join(app_dir, 'tools'))
  buildbot_common.MakeDir(os.path.join(app_dir, 'toolchain'))

  config = 'Release'

  filters = {}
  filters['DISABLE_PACKAGE'] = False
  filters['EXPERIMENTAL'] = False
  filters['TOOLS'] = toolchains
  filters['DEST'] = ['examples/api', 'examples/getting_started',
                     'examples/demo', 'examples/tutorial']
  tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters)
  build_projects.UpdateHelpers(app_dir, clobber=True)
  build_projects.UpdateProjects(app_dir, tree, clobber=False,
                                toolchains=toolchains, configs=[config],
                                first_toolchain=True)

  # Collect permissions from each example, and aggregate them.
  def MergeLists(list1, list2):
    return list1 + [x for x in list2 if x not in list1]
  all_permissions = []
  all_socket_permissions = []
  all_filesystem_permissions = []
  for _, project in parse_dsc.GenerateProjects(tree):
    permissions = project.get('PERMISSIONS', [])
    all_permissions = MergeLists(all_permissions, permissions)
    socket_permissions = project.get('SOCKET_PERMISSIONS', [])
    all_socket_permissions = MergeLists(all_socket_permissions,
                                        socket_permissions)
    filesystem_permissions = project.get('FILESYSTEM_PERMISSIONS', [])
    all_filesystem_permissions = MergeLists(all_filesystem_permissions,
                                            filesystem_permissions)
  if all_socket_permissions:
    all_permissions.append({'socket': all_socket_permissions})
  if all_filesystem_permissions:
    all_permissions.append({'fileSystem': all_filesystem_permissions})
  pretty_permissions = json.dumps(all_permissions, sort_keys=True, indent=4)

  for filename in ['background.js', 'icon128.png']:
    buildbot_common.CopyFile(os.path.join(sdk_resources_dir, filename),
                             os.path.join(app_examples_dir, filename))

  os.environ['NACL_SDK_ROOT'] = pepperdir

  build_projects.BuildProjects(app_dir, tree, deps=False, clean=False,
                               config=config)

  RemoveBuildCruft(app_dir)
  StripNexes(app_dir, platform, pepperdir)

  # Add manifest.json after RemoveBuildCruft... that function removes the
  # manifest.json files for the individual examples.
  name = 'Native Client SDK'
  if options.channel:
    name += ' (%s)' % options.channel
  template_dict = {
    'name': name,
    'channel': options.channel,
    'description':
        'Native Client SDK examples, showing API use and key concepts.',
    'key': False,  # manifests with "key" are rejected when uploading to CWS.
    'permissions': pretty_permissions,
    'version': build_version.ChromeVersionNoTrunk()
  }
  easy_template.RunTemplateFile(
      os.path.join(sdk_resources_dir, 'manifest.json.template'),
      os.path.join(app_examples_dir, 'manifest.json'),
      template_dict)

  app_zip = os.path.join(app_dir, 'examples.zip')
  os.chdir(app_examples_dir)
  oshelpers.Zip([app_zip, '-r', '*'])

  return 0


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
