#!/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 = {
  "codemirror-minified": "codemirror-minified",
  "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-icon-button": "polymer",
  "paper-input": "polymer",
  "paper-item": "polymer",
  "paper-listbox": "polymer",
  "paper-toggle-button": "polymer",
  "paper-styles": "polymer",
  "paper-tabs": "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:])
