# Copyright 2016 The Bazel Authors. All rights reserved.
#
# 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.
#
# Aspect for e4b, taken from intellij_info.bzl

DEPENDENCY_ATTRIBUTES = [
  "deps",
  "runtime_deps",
  "exports",
]

def struct_omit_none(**kwargs):
    d = {name: kwargs[name] for name in kwargs if kwargs[name] != None}
    return struct(**d)

def artifact_location(file):
  return None if file == None else file.path

def library_artifact(java_output):
  if java_output == None or java_output.class_jar == None:
    return None
  return struct_omit_none(
        jar = artifact_location(java_output.class_jar),
        interface_jar = artifact_location(java_output.ijar),
        source_jar = artifact_location(java_output.source_jar),
  )

def annotation_processing_jars(annotation_processing):
  return struct_omit_none(
        jar = artifact_location(annotation_processing.class_jar),
        source_jar = artifact_location(annotation_processing.source_jar),
  )

def jars_from_output(output):
  """ Collect jars for ide-resolve-files from Java output.
  """
  if output == None:
    return []
  return [jar
          for jar in [output.class_jar, output.ijar, output.source_jar]
          if jar != None and not jar.is_source]

def java_rule_ide_info(target, ctx):
  if hasattr(ctx.rule.attr, "srcs"):
     sources = [artifact_location(file)
                for src in ctx.rule.attr.srcs
                for file in src.files]
  else:
     sources = []

  jars = [library_artifact(output) for output in target.java.outputs.jars]
  ide_resolve_files = depset([jar
       for output in target.java.outputs.jars
       for jar in jars_from_output(output)])

  gen_jars = []
  if target.java.annotation_processing and target.java.annotation_processing.enabled:
    gen_jars = [annotation_processing_jars(target.java.annotation_processing)]
    ide_resolve_files = ide_resolve_files + depset([ jar
        for jar in [target.java.annotation_processing.class_jar,
                    target.java.annotation_processing.source_jar]
        if jar != None and not jar.is_source])

  return (struct_omit_none(
                 sources = sources,
                 jars = jars,
                 generated_jars = gen_jars
          ),
          ide_resolve_files)


def _aspect_impl(target, ctx):
  kind = ctx.rule.kind
  rule_attrs = ctx.rule.attr

  ide_info_text = depset()
  ide_resolve_files = depset()
  all_deps = []

  for attr_name in DEPENDENCY_ATTRIBUTES:
    if hasattr(rule_attrs, attr_name):
      deps = getattr(rule_attrs, attr_name)
      if type(deps) == 'list':
        for dep in deps:
          ide_info_text = ide_info_text + dep.intellij_info_files.ide_info_text
          ide_resolve_files = ide_resolve_files + dep.intellij_info_files.ide_resolve_files
        all_deps += [str(dep.label) for dep in deps]

  if hasattr(target, "java"):
    (java_rule_ide_info_struct, java_ide_resolve_files) = java_rule_ide_info(target, ctx)
    info = struct(
        label = str(target.label),
        kind = kind,
        dependencies = all_deps,
        build_file_artifact_location = ctx.build_file_path,
    ) + java_rule_ide_info_struct
    ide_resolve_files = ide_resolve_files + java_ide_resolve_files
    output = ctx.new_file(target.label.name + ".e4b-build.json")
    ctx.file_action(output, info.to_json())
    ide_info_text += depset([output])

  return struct(
      output_groups = {
        "ide-info-text" : ide_info_text,
        "ide-resolve" : ide_resolve_files,
      },
      intellij_info_files = struct(
        ide_info_text = ide_info_text,
        ide_resolve_files = ide_resolve_files,
      )
    )

e4b_aspect = aspect(implementation = _aspect_impl,
    attr_aspects = DEPENDENCY_ATTRIBUTES
)
"""Aspect for Eclipse 4 Bazel plugin.

This aspect produces information for IDE integration with Eclipse. This only
produces information for Java targets.

This aspect has two output groups:
  - ide-info-text produces .e4b-build.json files that contains information
    about target dependencies and sources files for the IDE.
  - ide-resolve build the dependencies needed for the build (i.e., artifacts
    generated by Java annotation processors).

An e4b-build.json file is a json blob with the following keys:
```javascript
{
  // Label of the corresponding target
  "label": "//package:target",
  // Kind of the corresponding target, e.g., java_test, java_binary, ...
  "kind": "java_library",
  // List of dependencies of this target
  "dependencies": ["//package1:dep1", "//package2:dep2"],
  "Path, relative to the workspace root, of the build file containing the target.
  "build_file_artifact_location": "package/BUILD",
  // List of sources file, relative to the execroot
  "sources": ["package/Test.java"],
  // List of jars created when building this target.
  "jars": [jar1, jar2],
  // List of jars generated by java annotation processors when building this target.
  "generated_jars": [genjar1, genjar2]
}
```

Jar files structure has the following keys:
```javascript
{
  // Location, relative to the execroot, of the jar file or null
  "jar": "bazel-out/host/package/libtarget.jar",
  // Location, relative to the execroot, of the interface jar file,
  // containing only the interfaces of the target jar or null.
  "interface_jar": "bazel-out/host/package/libtarget.interface-jar",
  // Location, relative to the execroot, of the source jar file,
  // containing the sources used to generate the target jar or null.
  "source_jar": "bazel-out/host/package/libtarget.interface-jar",
}
```
"""
