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

# Rule definitions loaded by default into every BUCK file.

include_defs('//tools/buck.defs')
include_defs('//tools/gwt-constants.defs')

def genantlr(
    name,
    srcs,
    out):
  tmp = name + '.src.zip'
  genrule(
    name = name,
    srcs = srcs,
    cmd = '$(exe //lib/antlr:antlr-tool) -o $TMP $SRCS;' +
      'cd $TMP;' +
      'zip -qr $OUT .',
    deps = ['//lib/antlr:antlr-tool'],
    out = out,
  )

def gwt_module(
    name,
    srcs,
    gwtxml = None,
    resources = [],
    deps = [],
    compile_deps = [],
    visibility = []):
  if gwtxml:
    resources = resources + [gwtxml]
  java_library(
    name = name,
    deps = deps + compile_deps,
    resources = srcs + resources,
    visibility = visibility,
  )
  java_library(
    name = name + '_lib',
    srcs = srcs,
    deps = [':' + name] + [d + '_lib' for d in deps] + compile_deps,
    visibility = visibility,
  )

def gwt_application(
    name,
    module_target,
    compiler_opts = [],
    compiler_jvm_flags = [],
    deps = [],
    visibility = []):
  cmd = ['$(exe //lib/gwt:compiler)', module_target, '$TMP', '$OUT']
  cmd += compiler_opts + ['--', '$DEPS']
  genrule(
    name = name,
    cmd = ' '.join(cmd),
    deps = [
      '//lib/gwt:compiler',
      '//lib/gwt:dev',
    ] + deps,
    out = '%s.zip' % name,
    visibility = visibility,
  )

# Compiles a Java library with additional compile-time dependencies
# that do not show up as transitive dependencies to java_library()
# or java_binary() rule that depends on this library.
def java_library2(
    name,
    srcs = [],
    resources = [],
    deps = [],
    compile_deps = [],
    visibility = []):
  c = name + '__compile'
  t = name + '__link'
  j = 'lib__%s__output/%s.jar' % (c, c)
  o = 'lib__%s__output/%s.jar' % (name, name)
  java_library(
    name = c,
    srcs = srcs,
    resources = resources,
    deps = deps + compile_deps,
    visibility = ['//tools/eclipse:classpath'],
  )
  # Break the dependency chain by passing the newly built
  # JAR to consumers through a prebuilt_jar().
  genrule(
    name = t,
    cmd = 'mkdir -p $(dirname $OUT);ln -s $SRCS $OUT',
    srcs = [genfile(j)],
    deps = [':' + c],
    out = o,
  )
  prebuilt_jar(
    name = name,
    binary_jar = genfile(o),
    deps = deps + [':' + t],
    visibility = visibility,
  )

def gerrit_extension(
    name,
    deps = [],
    compile_deps = [],
    srcs = [],
    resources = [],
    manifest_file = None,
    manifest_entries = [],
    visibility = ['PUBLIC']):
  gerrit_plugin(
    name = name,
    deps = deps,
    compile_deps = compile_deps,
    srcs = srcs,
    resources = resources,
    manifest_file = manifest_file,
    manifest_entries = manifest_entries,
    type = 'extension',
    visibility = visibility,
  )

def gerrit_plugin(
    name,
    deps = [],
    compile_deps = [],
    srcs = [],
    resources = [],
    gwt_module = None,
    manifest_file = None,
    manifest_entries = [],
    type = 'plugin',
    visibility = ['PUBLIC']):
  mf_cmd = 'v=$(git describe HEAD);'
  if manifest_file:
    mf_src = [manifest_file]
    mf_cmd += 'sed "s:@VERSION@:$v:g" $SRCS >$OUT'
  else:
    mf_src = []
    mf_cmd += 'echo "Manifest-Version: 1.0" >$OUT;'
    mf_cmd += 'echo "Gerrit-ApiType: %s" >>$OUT;' % type
    mf_cmd += 'echo "Implementation-Version: $v" >>$OUT;'
    mf_cmd += 'echo "Implementation-Vendor: Gerrit Code Review" >>$OUT'
    for line in manifest_entries:
      mf_cmd += ';echo "%s" >> $OUT' % line
  genrule(
    name = name + '__manifest',
    cmd = mf_cmd,
    srcs = mf_src,
    out = 'MANIFEST.MF',
  )
  gwt_deps = []
  static_jars = []
  if gwt_module:
    gwt_deps = GWT_PLUGIN_DEPS
    static_jars = [':%s-static-jar' % name]
  java_library2(
    name = name + '__plugin',
    srcs = srcs,
    resources = resources,
    deps = deps,
    compile_deps = ['//gerrit-%s-api:lib' % type] + compile_deps + gwt_deps,
  )
  if gwt_module:
    prebuilt_jar(
      name = '%s-static-jar' % name,
      binary_jar = genfile('%s-static.zip' % name),
      deps = [':%s-static' % name],
    )
    genrule(
      name = '%s-static' % name,
      cmd = 'mkdir -p $TMP/static' +
        ';unzip -qd $TMP/static $(location %s)' %
        ':%s__gwt_application' % name +
        ';cd $TMP' +
        ';zip -qr $OUT .',
      out = '%s-static.zip' % name,
      deps = [':%s__gwt_application' % name]
    )
    gwt_application(
      name = name + '__gwt_application',
      module_target = gwt_module,
      compiler_opts = GWT_COMPILER_OPTS,
      deps = [':%s__plugin' % name] + gwt_deps,
    )
  java_binary(
    name = name,
    manifest_file = genfile('MANIFEST.MF'),
    deps = [
      ':%s__plugin' % name,
      ':%s__manifest' % name,
    ] + static_jars,
    visibility = visibility,
  )

def java_sources(
    name,
    srcs,
    visibility = []
  ):
  java_library(
    name = name,
    resources = srcs,
    visibility = visibility,
  )

def java_doc(
    name,
    title,
    pkg,
    paths,
    srcs = [],
    deps = [],
    visibility = []
  ):
  genrule(
    name = name,
    cmd = ' '.join([
      'javadoc',
      '-quiet',
      '-protected',
      '-encoding UTF-8',
      '-charset UTF-8',
      '-notimestamp',
      '-windowtitle "' + title + '"',
      '-link http://docs.oracle.com/javase/7/docs/api',
      '-subpackages ' + pkg,
      '-sourcepath ',
      ':'.join([n for n in paths]),
      ' -classpath ',
      ':'.join(['$(location %s)' % n for n in deps]),
      '-d $TMP',
    ]) + ';jar cf $OUT -C $TMP .',
    srcs = srcs,
    deps = deps,
    out = name + '.jar',
    visibility = visibility,
)
