#!/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 decode(input):
    try:
        return input.decode("utf-8")
    except TypeError:
        return input


def bower_command(args):
    base = subprocess.check_output(["bazel", "info", "output_base"]).strip()
    exp = os.path.join(decode(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 decode(target_str).split('\n') if s]
    seeds = [s for s in decode(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(decode(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:])
