# 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")

jar_filetype = FileType([".jar"])

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

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

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.new_file(ctx.label.name + "_gwt.xml")
  ctx.file_action(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.new_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.action(
    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 = []
  for dep in deps:
    paths.append(dep.path)

  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 = "external/local_jdk/bin/java %s -Dgwt.normalizeTimestamps=true -cp %s %s -war %s -deploy %s " % (
    " ".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.action(
    inputs = list(deps) + ctx.files._jdk + ctx.files._zip + gwt_user_agent_modules,
    outputs = [output_zip],
    mnemonic = "GwtBinary",
    progress_message = "GWT compiling " + output_zip.short_path,
    command = "set -e\n" + cmd,
  )

def _get_transitive_closure(ctx):
  deps = depset()
  for dep in ctx.attr.module_deps:
    deps = deps + dep.java.transitive_runtime_deps
    deps = deps + dep.java.transitive_source_jars
  for dep in ctx.attr.deps:
    if hasattr(dep, 'java'):
      deps = deps + dep.java.transitive_runtime_deps
    elif hasattr(dep, 'files'):
      deps = deps + dep.files

  return deps

gwt_binary = rule(
    attrs = {
        "user_agent": attr.string(),
        "style": attr.string(default = "OBF"),
        "optimize": attr.string(default = "9"),
        "deps": attr.label_list(allow_files = jar_filetype),
        "module": attr.string_list(default = [MODULE]),
        "module_deps": attr.label_list(allow_files = jar_filetype),
        "compiler_args": attr.string_list(),
        "jvm_args": attr.string_list(),
        "_jdk": attr.label(
            default = Label("//tools/defaults:jdk"),
        ),
        "_zip": attr.label(
            default = Label("@bazel_tools//tools/zip:zipper"),
            cfg = "host",
            executable = True,
            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,
    )
