#!/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",
  "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-input": "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",
  "polymer": "polymer",
  "promise-polyfill": "promise-polyfill",
  "web-animations-js": "Apache2.0",
  "webcomponentsjs": "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

    # TODO(hanwen): bower packages can also have 'fully qualified'
    # names, ("PolymerElements/iron-ajax") as well as short names
    # ("iron-ajax").  It is possible for bower.json files to refer to
    # long names as their dependencies. If any package does this, we
    # will have to either 1) strip off the prefix (typically github
    # user?), or 2) build a map of short name <=> fully qualified
    # name. For now, we just ignore the problem.
    pkg["normalized-name"] = pkg["name"]
    data.append(pkg)

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


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