# 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/bzl:genrule2.bzl', 'genrule2')
load('//tools/bzl: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',
]

PLUGIN_DEPS_NEVERLINK = [
  '//gerrit-plugin-api:lib-neverlink',
]

GWT_PLUGIN_DEPS_NEVERLINK = [
  '//gerrit-plugin-gwtui:gwtui-api-lib-neverlink',
  '//lib/gwt:user-neverlink',
]

GWT_PLUGIN_DEPS = [
  '//gerrit-plugin-gwtui:gwtui-api-lib',
]

GWT_TRANSITIVE_DEPS = [
  '//lib/gwt:ant',
  '//lib/gwt:colt',
  '//lib/gwt:javax-validation',
  '//lib/gwt:javax-validation_src',
  '//lib/gwt:jsinterop-annotations',
  '//lib/gwt:jsinterop-annotations_src',
  '//lib/gwt:tapestry',
  '//lib/gwt:w3c-css-sac',
  '//lib/ow2:ow2-asm',
  '//lib/ow2:ow2-asm-analysis',
  '//lib/ow2:ow2-asm-commons',
  '//lib/ow2:ow2-asm-tree',
  '//lib/ow2:ow2-asm-util',
]

DEPS = GWT_TRANSITIVE_DEPS + [
  '//gerrit-gwtexpui:CSS',
  '//lib:gwtjsonrpc',
  '//lib/gwt:dev',
  '@jgit//jar:src',
]

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 += [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 += " ".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 = set()
  for dep in ctx.attr.module_deps:
    deps += dep.java.transitive_runtime_deps
    deps += dep.java.transitive_source_jars
  for dep in ctx.attr.deps:
    if hasattr(dep, 'java'):
      deps += dep.java.transitive_runtime_deps
    elif hasattr(dep, 'files'):
      deps += dep.files

  return deps

gwt_binary = rule(
  implementation = _gwt_binary_impl,
  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",
  },
)

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 gen_ui_module(name, suffix = ""):
  gwt_module(
    name = name + suffix,
    srcs = native.glob(['src/main/java/**/*.java']),
    gwt_xml = 'src/main/java/%s.gwt.xml' % MODULE.replace('.', '/'),
    resources = native.glob(
        ['src/main/java/**/*'],
        exclude = ['src/main/java/**/*.java'] +
        ['src/main/java/%s.gwt.xml' % MODULE.replace('.', '/')]),
    deps = [
      '//gerrit-gwtui-common:diffy_logo',
      '//gerrit-gwtui-common:client',
      '//gerrit-gwtexpui:CSS',
      '//lib/codemirror:codemirror' + suffix,
      '//lib/gwt:user',
    ],
    visibility = ['//visibility:public'],
  )

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,
    )
