# Copyright (C) 2016 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.

# Port of Buck native gwt_binary() rule. See discussion in context of
# https://github.com/facebook/buck/issues/109
load("//tools:genrule2.bzl", "genrule2")
load("//tools:java.bzl", "java_library2")

BROWSERS = [
    "chrome",
    "firefox",
    "gecko1_8",
    "safari",
    "msie",
    "ie8",
    "ie9",
    "ie10",
    "edge",
]

ALIASES = {
    "chrome": "safari",
    "edge": "gecko1_8",
    "firefox": "gecko1_8",
    "msie": "ie10",
}

MODULE = "com.google.gerrit.GerritGwtUI"

GWT_COMPILER = "com.google.gwt.dev.Compiler"

GWT_JVM_ARGS = ["-Xmx512m"]

GWT_COMPILER_ARGS = [
    "-XdisableClassMetadata",
]

GWT_COMPILER_ARGS_RELEASE_MODE = GWT_COMPILER_ARGS + [
    "-XdisableCastChecking",
]

GWT_PLUGIN_DEPS_NEVERLINK = [
    "//external:gerrit-plugin-gwtui-neverlink",
    "//external:gwt-user-neverlink",
]

GWT_PLUGIN_DEPS = [
    "//external:gerrit-plugin-gwtui",
]

GWT_TRANSITIVE_DEPS = [
    "//external:ant",
    "//external:colt",
    "//external:javax-validation",
    "//external:javax-validation-src",
    "//external:jsinterop-annotations",
    "//external:jsinterop-annotations-src",
    "//external:jsr305",
    "//external:tapestry",
    "//external:w3c-css-sac",
    "//external:ow2-asm",
    "//external:ow2-asm-analysis",
    "//external:ow2-asm-commons",
    "//external:ow2-asm-tree",
    "//external:ow2-asm-util",
]

DEPS = GWT_TRANSITIVE_DEPS + [
    "//:gwt-dev",
]

USER_AGENT_XML = """<module rename-to='gerrit_ui'>
<inherits name='%s'/>
<set-property name='user.agent' value='%s'/>
<set-property name='locale' value='default'/>
</module>
"""

def gwt_module(gwt_xml = None, resources = [], srcs = [], **kwargs):
    if gwt_xml:
        resources = resources + [gwt_xml]

    java_library2(
        srcs = srcs,
        resources = resources,
        **kwargs
    )

def _gwt_user_agent_module(ctx):
    """Generate user agent specific GWT module."""
    if not ctx.attr.user_agent:
        return None

    ua = ctx.attr.user_agent
    impl = ua
    if ua in ALIASES:
        impl = ALIASES[ua]

    # intermediate artifact: user agent speific GWT xml file
    gwt_user_agent_xml = ctx.actions.declare_file(ctx.label.name + "_gwt.xml")
    ctx.actions.write(
        output = gwt_user_agent_xml,
        content = USER_AGENT_XML % (MODULE, impl),
    )

    # intermediate artifact: user agent specific zip with GWT module
    gwt_user_agent_zip = ctx.actions.declare_file(ctx.label.name + "_gwt.zip")
    gwt = "%s_%s.gwt.xml" % (MODULE.replace(".", "/"), ua)
    dir = gwt_user_agent_zip.path + ".dir"
    cmd = " && ".join([
        "p=$PWD",
        "mkdir -p %s" % dir,
        "cd %s" % dir,
        "mkdir -p $(dirname %s)" % gwt,
        "cp $p/%s %s" % (gwt_user_agent_xml.path, gwt),
        "$p/%s cC $p/%s $(find . | sed 's|^./||')" % (ctx.executable._zip.path, gwt_user_agent_zip.path),
    ])
    ctx.actions.run_shell(
        inputs = [gwt_user_agent_xml] + ctx.files._zip,
        outputs = [gwt_user_agent_zip],
        command = cmd,
        mnemonic = "GenerateUserAgentGWTModule",
    )

    return struct(
        zip = gwt_user_agent_zip,
        module = MODULE + "_" + ua,
    )

def _gwt_binary_impl(ctx):
    module = ctx.attr.module[0]
    output_zip = ctx.outputs.output
    output_dir = output_zip.path + ".gwt_output"
    deploy_dir = output_zip.path + ".gwt_deploy"

    deps = _get_transitive_closure(ctx)

    paths = [dep.path for dep in deps.to_list()]

    gwt_user_agent_modules = []
    ua = _gwt_user_agent_module(ctx)
    if ua:
        paths.append(ua.zip.path)
        gwt_user_agent_modules.append(ua.zip)
        module = ua.module

    cmd = "%s %s -Dgwt.normalizeTimestamps=true -cp %s %s -war %s -deploy %s " % (
        ctx.attr._jdk[java_common.JavaRuntimeInfo].java_executable_exec_path,
        " ".join(ctx.attr.jvm_args),
        ":".join(paths),
        GWT_COMPILER,
        output_dir,
        deploy_dir,
    )

    # TODO(davido): clean up command concatenation
    cmd = cmd + " ".join([
        "-style %s" % ctx.attr.style,
        "-optimize %s" % ctx.attr.optimize,
        "-strict",
        " ".join(ctx.attr.compiler_args),
        module + "\n",
        "rm -rf %s/gwt-unitCache\n" % output_dir,
        "root=`pwd`\n",
        "cd %s; $root/%s Cc ../%s $(find .)\n" % (
            output_dir,
            ctx.executable._zip.path,
            output_zip.basename,
        ),
    ])

    ctx.actions.run_shell(
        inputs = depset(direct = gwt_user_agent_modules, transitive = [deps]),
        outputs = [output_zip],
        tools = ctx.files._jdk + ctx.files._zip,
        mnemonic = "GwtBinary",
        progress_message = "GWT compiling " + output_zip.short_path,
        command = "set -e\n" + cmd,
    )

def _get_transitive_closure(ctx):
    deps = []
    for dep in ctx.attr.module_deps:
        deps.append(dep[JavaInfo].transitive_runtime_deps)
        deps.append(dep[JavaInfo].transitive_source_jars)
    for dep in ctx.attr.deps:
        if JavaInfo in dep:
            deps.append(dep[JavaInfo].transitive_runtime_deps)
        elif hasattr(dep, "files"):
            deps.append(dep.files)

    return depset(transitive = deps)

gwt_binary = rule(
    attrs = {
        "compiler_args": attr.string_list(),
        "jvm_args": attr.string_list(),
        "module": attr.string_list(default = [MODULE]),
        "module_deps": attr.label_list(allow_files = [".jar"]),
        "optimize": attr.string(default = "9"),
        "style": attr.string(default = "OBF"),
        "user_agent": attr.string(),
        "deps": attr.label_list(allow_files = [".jar"]),
        "_jdk": attr.label(
            default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
            cfg = "host",
        ),
        "_zip": attr.label(
            default = Label("@bazel_tools//tools/zip:zipper"),
            cfg = "host",
            executable = True,
            allow_single_file = True,
        ),
    },
    outputs = {
        "output": "%{name}.zip",
    },
    implementation = _gwt_binary_impl,
)

def gwt_genrule(suffix = ""):
    dbg = "ui_dbg" + suffix
    opt = "ui_opt" + suffix
    module_dep = ":ui_module" + suffix
    args = GWT_COMPILER_ARGS_RELEASE_MODE if suffix == "_r" else GWT_COMPILER_ARGS

    genrule2(
        name = "ui_optdbg" + suffix,
        srcs = [
            ":" + dbg,
            ":" + opt,
        ],
        cmd = "cd $$TMP;" +
              "unzip -q $$ROOT/$(location :%s);" % dbg +
              "mv" +
              " gerrit_ui/gerrit_ui.nocache.js" +
              " gerrit_ui/dbg_gerrit_ui.nocache.js;" +
              "unzip -qo $$ROOT/$(location :%s);" % opt +
              "mkdir -p $$(dirname $@);" +
              "zip -qr $$ROOT/$@ .",
        outs = ["ui_optdbg" + suffix + ".zip"],
        visibility = ["//visibility:public"],
    )

    gwt_binary(
        name = opt,
        module = [MODULE],
        module_deps = [module_dep],
        deps = DEPS,
        compiler_args = args,
        jvm_args = GWT_JVM_ARGS,
    )

    gwt_binary(
        name = dbg,
        style = "PRETTY",
        optimize = "0",
        module_deps = [module_dep],
        deps = DEPS,
        compiler_args = GWT_COMPILER_ARGS,
        jvm_args = GWT_JVM_ARGS,
    )

def gwt_user_agent_permutations():
    for ua in BROWSERS:
        gwt_binary(
            name = "ui_%s" % ua,
            user_agent = ua,
            style = "PRETTY",
            optimize = "0",
            module = [MODULE],
            module_deps = [":ui_module"],
            deps = DEPS,
            compiler_args = GWT_COMPILER_ARGS,
            jvm_args = GWT_JVM_ARGS,
        )
