# 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('//lib/auto/auto_value.defs')
include_defs('//tools/gwt-constants.defs')
include_defs('//tools/java_doc.defs')
include_defs('//tools/java_sources.defs')
import copy

# Set defaults on java rules:
#  - Add AutoValue annotation processing support.
#  - Treat source files as UTF-8.

_buck_java_library = java_library
def java_library(*args, **kwargs):
  _munge_args(kwargs)
  _buck_java_library(*args, **kwargs)

_buck_java_test = java_test
def java_test(*args, **kwargs):
  _munge_args(kwargs)
  _buck_java_test(*args, **kwargs)


# Munge kwargs to set Gerrit-specific defaults.
def _munge_args(kwargs):
  _set_auto_value(kwargs)
  _set_extra_arguments(kwargs)

def _set_extra_arguments(kwargs):
  ext = 'extra_arguments'
  if ext not in kwargs:
    kwargs[ext] = []
  extra_args = kwargs[ext]

  for arg in extra_args:
    if arg.startswith('-encoding'):
      return

  extra_args.extend(['-encoding', 'UTF-8'])

def _set_auto_value(kwargs):
  apk = 'annotation_processors'
  if apk not in kwargs:
    kwargs[apk] = []
  aps = kwargs.get(apk, [])

  apdk = 'annotation_processor_deps'
  if apdk not in kwargs:
    kwargs[apdk] = []
  apds = kwargs.get(apdk, [])

  if AUTO_VALUE_DEP in kwargs.get('deps', []):
    aps.extend(AUTO_VALUE_PROCESSORS)
    apds.extend(AUTO_VALUE_PROCESSOR_DEPS)


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

def gwt_module(gwt_xml=None, **kwargs):
  kw = copy.deepcopy(kwargs)
  if 'resources' not in kw:
    kw['resources'] = []
  if gwt_xml:
    kw['resources'] += [gwt_xml]
  if 'srcs' in kw:
    kw['resources'] += kw['srcs']

  # Buck does not accept duplicate resources. Callers may have
  # included gwt_xml or srcs as part of resources, so de-dupe.
  kw['resources'] = list(set(kw['resources']))

  java_library(**kw)

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

def gerrit_plugin(
    name,
    deps = [],
    provided_deps = [],
    srcs = [],
    resources = [],
    gwt_module = None,
    manifest_file = None,
    manifest_entries = [],
    type = 'plugin',
    visibility = ['PUBLIC']):
  from multiprocessing import cpu_count
  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:
      line = line.replace('$', '\$')
      mf_cmd += ';echo "%s" >> $OUT' % line
  genrule(
    name = name + '__manifest',
    cmd = mf_cmd,
    srcs = mf_src,
    out = 'MANIFEST.MF',
  )
  static_jars = []
  if gwt_module:
    static_jars = [':%s-static-jar' % name]
  java_library(
    name = name + '__plugin',
    srcs = srcs,
    resources = resources,
    deps = deps,
    provided_deps = ['//gerrit-%s-api:lib' % type] +
      provided_deps +
      GWT_PLUGIN_DEPS,
    visibility = ['PUBLIC'],
  )
  if gwt_module:
    java_library(
      name = name + '__gwt_module',
      srcs = [],
      resources = list(set(srcs + resources)),
      deps = deps,
      provided_deps = GWT_PLUGIN_DEPS,
      visibility = ['PUBLIC'],
    )
    prebuilt_jar(
      name = '%s-static-jar' % name,
      binary_jar = ':%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,
    )
    gwt_binary(
      name = name + '__gwt_application',
      modules = [gwt_module],
      deps = GWT_PLUGIN_DEPS + ['//lib/gwt:dev'],
      module_deps = [':%s__gwt_module' % name],
      local_workers = cpu_count(),
      strict = True,
      experimental_args = GWT_COMPILER_ARGS,
      vm_args = GWT_JVM_ARGS,
    )

  java_binary(
    name = name,
    manifest_file = ':%s__manifest' % name,
    merge_manifests = False,
    deps = [
      ':%s__plugin' % name,
    ] + static_jars,
    visibility = visibility,
  )
