# 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

# Add AutoValue support to java_library.
_buck_java_library = java_library
def java_library(*args, **kwargs):
  _set_auto_value(kwargs)
  _buck_java_library(*args, **kwargs)

# Add AutoValue support to java_test.
_buck_java_test = java_test
def java_test(*args, **kwargs):
  _set_auto_value(kwargs)
  _buck_java_test(*args, **kwargs)

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',
  )
  gwt_deps = []
  static_jars = []
  if gwt_module:
    gwt_deps = GWT_PLUGIN_DEPS
    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_deps,
    visibility = ['PUBLIC'],
  )
  if gwt_module:
    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_deps,
      module_deps = [':%s__plugin' % 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,
  )
