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

# War packaging.

jar_filetype = FileType([".jar"])

def _add_context(in_file, output):
  input_path = in_file.path
  return [
    'unzip -qd %s %s' % (output, input_path)
  ]

def _add_file(name, in_file, output):
  output_path = output
  input_path = in_file.path
  short_path = in_file.short_path
  n = in_file.basename

  if n != 'web.xml' and short_path.startswith('%s-' % name):
    n = short_path.split('/')[0] + '-' + n

  output_path = output_path + n

  return [
    'test -L %s || ln -s $(pwd)/%s %s' % (output_path, input_path, output_path)
  ]

def _make_war(input_dir, output):
  return '(%s)' % ' && '.join([
    'root=$(pwd)',
    'cd %s' % input_dir,
    "find . -exec touch -t 198001010000 '{}' ';' 2> /dev/null",
    'zip -9qr ${root}/%s .' % (output.path),
  ])

def _war_impl(ctx):
  war = ctx.outputs.war
  build_output = war.path + '.build_output'
  inputs = []

  cmd = [
    'set -e;rm -rf ' + build_output,
    'mkdir -p ' + build_output,
    'mkdir -p %s/WEB-INF/lib' % build_output,
  ]

  transitive_lib_deps = depset()
  for l in ctx.attr.libs:
    if hasattr(l, 'java'):
      transitive_lib_deps = transitive_lib_deps + l.java.transitive_runtime_deps
    elif hasattr(l, 'files'):
      transitive_lib_deps = transitive_lib_deps + l.files

  for dep in transitive_lib_deps:
    cmd = cmd + _add_file(ctx.attr.name, dep, build_output + '/WEB-INF/lib/')
    inputs.append(dep)

  if ctx.attr.web_xml:
    for web_xml in ctx.attr.web_xml.files:
      inputs.append(web_xml)
      cmd = cmd + _add_file(ctx.attr.name, web_xml, build_output + '/WEB-INF/')

  transitive_context_deps = depset()
  if ctx.attr.context:
    for jar in ctx.attr.context:
      if hasattr(jar, 'java'):
        transitive_context_deps = transitive_context_deps + jar.java.transitive_runtime_deps
      elif hasattr(jar, 'files'):
        transitive_context_deps = transitive_context_deps + jar.files
  for dep in transitive_context_deps:
    cmd = cmd + _add_context(dep, build_output)
    inputs.append(dep)

  # Add zip war
  cmd.append(_make_war(build_output, war))

  ctx.action(
    inputs = inputs,
    outputs = [war],
    mnemonic = 'WAR',
    command = '\n'.join(cmd),
    use_default_shell_env = True,
  )

# context: go to the root directory
# libs: go to the WEB-INF/lib directory
# web_xml: go to the WEB-INF directory
_pkg_war = rule(
    attrs = {
        "context": attr.label_list(allow_files = True),
        "libs": attr.label_list(allow_files = jar_filetype),
        "web_xml": attr.label(allow_files = True),
    },
    outputs = {"war": "%{name}.war"},
    implementation = _war_impl,
)

def pkg_war(name, context = [], **kwargs):
  _pkg_war(
    name = name,
    context = context,
    **kwargs
  )
