# 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')
include_defs('//tools/git.defs')
import copy
import traceback
import os
from multiprocessing import cpu_count

# 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, [])

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


# Add 'license' argument to genrule.
_buck_genrule = genrule
def genrule(*args, **kwargs):
  license = kwargs.pop('license', None)
  if license:
    license = '//lib:LICENSE-%s' % license
    # genrule has no deps attribute, but locations listed in the command show
    # up as deps of the target with buck audit.
    kwargs['cmd'] = 'true $(location %s); %s' % (license, kwargs['cmd'])
  _buck_genrule(*args, **kwargs)


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'],
    target_suffix = ''):
  tb = traceback.extract_stack()
  calling_BUCK_file = tb[-2][0]
  calling_BUCK_dir = os.path.abspath(os.path.dirname(calling_BUCK_file))
  mf_cmd = 'v=%s;' % git_describe(calling_BUCK_dir)
  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 + GWT_TRANSITIVE_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 + target_suffix,
    manifest_file = ':%s__manifest' % name,
    merge_manifests = False,
    deps = [
      ':%s__plugin' % name,
    ] + static_jars,
    visibility = visibility,
  )
