#!/usr/bin/env python
# Copyright (C) 2015 The Android Open Source Project
#
# 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.

"""Suggested call sequence:

python tools/js/bower2bazel.py -w lib/js/bower_archives.bzl -b lib/js/bower_components.bzl
"""

from __future__ import print_function

import collections
import json
import hashlib
import optparse
import os
import subprocess
import sys
import tempfile
import glob
import bowerutil

# list of licenses for packages that don't specify one in their bower.json file.
package_licenses = {
  "es6-promise": "es6-promise",
  "fetch": "fetch",
  "font-roboto": "polymer",
  "iron-a11y-announcer": "polymer",
  "iron-a11y-keys-behavior": "polymer",
  "iron-autogrow-textarea": "polymer",
  "iron-behaviors": "polymer",
  "iron-dropdown": "polymer",
  "iron-fit-behavior": "polymer",
  "iron-flex-layout": "polymer",
  "iron-form-element-behavior": "polymer",
  "iron-icon": "polymer",
  "iron-iconset-svg": "polymer",
  "iron-input": "polymer",
  "iron-menu-behavior": "polymer",
  "iron-meta": "polymer",
  "iron-overlay-behavior": "polymer",
  "iron-resizable-behavior": "polymer",
  "iron-selector": "polymer",
  "iron-validatable-behavior": "polymer",
  "moment": "moment",
  "neon-animation": "polymer",
  "page": "page.js",
  "paper-button": "polymer",
  "paper-input": "polymer",
  "paper-item": "polymer",
  "paper-listbox": "polymer",
  "paper-styles": "polymer",
  "polymer": "polymer",
  "polymer-resin": "polymer",
  "promise-polyfill": "promise-polyfill",
  "web-animations-js": "Apache2.0",
  "webcomponentsjs": "polymer",
  "paper-material": "polymer",
  "paper-styles": "polymer",
  "paper-behaviors": "polymer",
  "paper-ripple": "polymer",
  "iron-checked-element-behavior": "polymer",
  "font-roboto": "polymer",
}


def build_bower_json(version_targets, seeds):
  """Generate bower JSON file, return its path.

  Args:
    version_targets: bazel target names of the versions.json file.
    seeds: an iterable of bower package names of the seed packages, ie.
      the packages whose versions we control manually.
  """
  bower_json = collections.OrderedDict()
  bower_json['name'] = 'bower2bazel-output'
  bower_json['version'] = '0.0.0'
  bower_json['description'] = 'Auto-generated bower.json for dependency management'
  bower_json['private'] = True
  bower_json['dependencies'] = {}

  seeds = set(seeds)
  for v in version_targets:
    path = os.path.join("bazel-out/*-fastbuild/bin", v.lstrip("/").replace(":", "/"))
    fs = glob.glob(path)
    assert len(fs) == 1, '%s: file not found or multiple files found: %s' % (path, fs)
    with open(fs[0]) as f:
      j = json.load(f)
      if "" in j:
        # drop dummy entries.
        del j[""]

      trimmed = {}
      for k, v in j.items():
        if k in seeds:
          trimmed[k] = v

      bower_json['dependencies'].update(trimmed)

  tmpdir = tempfile.mkdtemp()
  ret = os.path.join(tmpdir, 'bower.json')
  with open(ret, 'w') as f:
    json.dump(bower_json, f, indent=2)
  return ret


def bower_command(args):
  base = subprocess.check_output(["bazel", "info", "output_base"]).strip()
  exp = os.path.join(base, "external", "bower", "*npm_binary.tgz")
  fs = sorted(glob.glob(exp))
  assert len(fs) == 1, "bower tarball not found or have multiple versions %s" % fs
  return ["python", os.getcwd() + "/tools/js/run_npm_binary.py", sorted(fs)[0]] + args


def main(args):
  opts = optparse.OptionParser()
  opts.add_option('-w', help='.bzl output for WORKSPACE')
  opts.add_option('-b', help='.bzl output for //lib:BUILD')
  opts, args = opts.parse_args()

  target_str = subprocess.check_output([
    "bazel", "query", "kind(bower_component_bundle, //polygerrit-ui/...)"])
  seed_str = subprocess.check_output([
    "bazel", "query", "attr(seed, 1, kind(bower_component, deps(//polygerrit-ui/...)))"])
  targets = [s for s in target_str.split('\n') if s]
  seeds = [s for s in seed_str.split('\n') if s]
  prefix = "//lib/js:"
  non_seeds = [s for s in seeds if not s.startswith(prefix)]
  assert not non_seeds, non_seeds
  seeds = set([s[len(prefix):] for s in seeds])

  version_targets = [t + "-versions.json" for t in targets]
  subprocess.check_call(['bazel', 'build'] + version_targets)
  bower_json_path = build_bower_json(version_targets, seeds)
  dir = os.path.dirname(bower_json_path)
  cmd = bower_command(["install"])

  build_out = sys.stdout
  if opts.b:
    build_out = open(opts.b + ".tmp", 'w')

  ws_out = sys.stdout
  if opts.b:
    ws_out = open(opts.w + ".tmp", 'w')

  header = """# DO NOT EDIT
# generated with the following command:
#
#   %s
#

""" % ' '.join(sys.argv)

  ws_out.write(header)
  build_out.write(header)

  oldwd = os.getcwd()
  os.chdir(dir)
  subprocess.check_call(cmd)

  interpret_bower_json(seeds, ws_out, build_out)
  ws_out.close()
  build_out.close()

  os.chdir(oldwd)
  os.rename(opts.w + ".tmp", opts.w)
  os.rename(opts.b + ".tmp", opts.b)


def dump_workspace(data, seeds, out):
  out.write('load("//tools/bzl:js.bzl", "bower_archive")\n\n')
  out.write('def load_bower_archives():\n')

  for d in data:
    if d["name"] in seeds:
      continue
    out.write("""  bower_archive(
    name = "%(name)s",
    package = "%(normalized-name)s",
    version = "%(version)s",
    sha1 = "%(bazel-sha1)s")
""" % d)


def dump_build(data, seeds, out):
  out.write('load("//tools/bzl:js.bzl", "bower_component")\n\n')
  out.write('def define_bower_components():\n')
  for d in data:
    out.write("  bower_component(\n")
    out.write("    name = \"%s\",\n" % d["name"])
    out.write("    license = \"//lib:LICENSE-%s\",\n" % d["bazel-license"])
    deps = sorted(d.get("dependencies", {}).keys())
    if deps:
      if len(deps) == 1:
        out.write("    deps = [ \":%s\" ],\n" % deps[0])
      else:
        out.write("    deps = [\n")
        for dep in deps:
          out.write("      \":%s\",\n" % dep)
        out.write("    ],\n")
    if d["name"] in seeds:
      out.write("    seed = True,\n")
    out.write("  )\n")
  # done


def interpret_bower_json(seeds, ws_out, build_out):
  out = subprocess.check_output(["find", "bower_components/", "-name", ".bower.json"])

  data = []
  for f in sorted(out.split('\n')):
    if not f:
      continue
    pkg = json.load(open(f))
    pkg_name = pkg["name"]

    pkg["bazel-sha1"] = bowerutil.hash_bower_component(
      hashlib.sha1(), os.path.dirname(f)).hexdigest()
    license = package_licenses.get(pkg_name, "DO_NOT_DISTRIBUTE")

    pkg["bazel-license"] = license
    pkg["normalized-name"] = pkg["_originalSource"]
    data.append(pkg)

  dump_workspace(data, seeds, ws_out)
  dump_build(data, seeds, build_out)


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