# 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.
#  - std_out_log_level = info (the default is too spammy)

_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)
  _do_not_spam_std_out(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 _do_not_spam_std_out(kwargs):
  level = 'std_out_log_level'
  if level not in kwargs:
    kwargs[level] = 'INFO'

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