# Copyright 2018 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.
"""Bazel Android Data Binding."""

load("//rules:providers.bzl", "DataBindingV2Info")
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
load(":utils.bzl", "ANDROID_TOOLCHAIN_TYPE", _utils = "utils")

visibility(PROJECT_VISIBILITY)

# Data Binding context attributes.
_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS = \
    "java_annotation_processor_additional_inputs"
_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS = \
    "java_annotation_processor_additional_outputs"
_JAVA_PLUGINS = "java_plugins"
_JAVA_SRCS = "java_srcs"
_JAVAC_OPTS = "javac_opts"
_PROVIDERS = "providers"

DataBindingContextInfo = provider(
    doc = "Contains data from processing Android Data Binding.",
    fields = {
        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: (
            "Additional inputs required by the Java annotation processor."
        ),
        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: (
            "Additional outputs produced by the Java annotation processor."
        ),
        _JAVA_PLUGINS: "Data Binding Java annotation processor",
        _JAVA_SRCS: "Java sources required by the Java annotation processor.",
        _JAVAC_OPTS: (
            "Additional Javac opts required by the Java annotation processor."
        ),
        _PROVIDERS: "The list of all providers to propagate.",
    },
)

# Path used when resources have not been defined.
_NO_RESOURCES_PATH = "/tmp/no_resources"

def _copy_annotation_file(ctx, output_dir, annotation_template):
    annotation_out = ctx.actions.declare_file(
        output_dir + "/android/databinding/layouts/DataBindingInfo.java",
    )
    _utils.copy_file(ctx, annotation_template, annotation_out)
    return annotation_out

def _gen_sources(ctx, output_dir, java_package, deps, layout_info, data_binding_exec):
    class_info = ctx.actions.declare_file(output_dir + "class-info.zip")
    srcjar = ctx.actions.declare_file(output_dir + "baseClassSrc.srcjar")

    args = ctx.actions.args()
    args.add("-layoutInfoFiles", layout_info)
    args.add("-package", java_package)
    args.add("-classInfoOut", class_info)
    args.add("-sourceOut", srcjar)
    args.add("-zipSourceOutput", "true")
    args.add("-useAndroidX", "false")

    if deps:
        if type(deps[0].class_infos) == "depset":
            class_infos = depset(transitive = [info.class_infos for info in deps])
            inputs = depset(direct = [layout_info], transitive = [class_infos])
        elif type(deps[0].class_infos) == "list":
            class_infos = []
            for info in deps:
                class_infos.extend(info.class_infos)
            inputs = class_infos + [layout_info]
        else:
            fail("Expected list or depset. Got %s" % type(deps[0].class_infos))
    else:
        class_infos = []
        inputs = [layout_info]

    args.add_all(class_infos, before_each = "-dependencyClassInfoList")

    ctx.actions.run(
        executable = data_binding_exec,
        arguments = ["GEN_BASE_CLASSES", args],
        inputs = inputs,
        outputs = [class_info, srcjar],
        mnemonic = "GenerateDataBindingBaseClasses",
        progress_message = (
            "GenerateDataBindingBaseClasses %s" % class_info.short_path
        ),
        toolchain = ANDROID_TOOLCHAIN_TYPE,
    )
    return srcjar, class_info

def _setup_dependent_lib_artifacts(ctx, output_dir, deps):
    # DataBinding requires files in very specific locations.
    # The following expand_template (copy actions) are moving the files
    # to the correct locations.
    dep_lib_artifacts = []
    for info in deps:
        # Yes, DataBinding requires depsets iterations.
        for artifact in (info.transitive_br_files.to_list() +
                         _utils.list_or_depset_to_list(info.setter_stores) +
                         _utils.list_or_depset_to_list(info.class_infos)):
            # short_path might contain a parent directory reference if the
            # databinding artifact is from an external repository (e.g. an aar
            # from Maven). If that's the case, just remove the parent directory
            # reference, otherwise the "dependent-lib-artifacts" directory will
            # get removed by the "..".
            path = artifact.short_path
            if path.startswith("../"):
                path = path[3:]
            dep_lib_artifact = ctx.actions.declare_file(
                output_dir + "dependent-lib-artifacts/" + path,
            )

            # Copy file to a location required by the DataBinding annotation
            # processor.
            # TODO(djwhang): Look into SymlinkAction.
            if artifact.is_directory:
                _utils.copy_dir(ctx, artifact, dep_lib_artifact)
            else:
                _utils.copy_file(ctx, artifact, dep_lib_artifact)
            dep_lib_artifacts.append(dep_lib_artifact)
    return dep_lib_artifacts

def _get_javac_opts(
        ctx,
        java_package,
        artifact_type,
        dependency_artifacts_dir,
        aar_out_dir,
        class_info_path,
        layout_info_path,
        deps):
    java_packages = []
    for info in deps:
        for label_and_java_package in info.label_and_java_packages:
            java_packages.append(label_and_java_package.java_package)

    javac_opts = []
    javac_opts.append("-Aandroid.databinding.dependencyArtifactsDir=" +
                      dependency_artifacts_dir)
    javac_opts.append("-Aandroid.databinding.aarOutDir=" + aar_out_dir)
    javac_opts.append("-Aandroid.databinding.sdkDir=/not/used")
    javac_opts.append("-Aandroid.databinding.artifactType=" + artifact_type)
    javac_opts.append("-Aandroid.databinding.exportClassListOutFile=" +
                      "/tmp/exported_classes")
    javac_opts.append("-Aandroid.databinding.modulePackage=" + java_package)
    javac_opts.append("-Aandroid.databinding.directDependencyPkgs=[%s]" %
                      ",".join(java_packages))

    # The minimum Android SDK compatible with this rule.
    # TODO(djwhang): This probably should be based on the actual min-sdk from
    # the manifest, or an appropriate rule attribute.
    javac_opts.append("-Aandroid.databinding.minApi=14")
    javac_opts.append("-Aandroid.databinding.enableV2=1")

    javac_opts.append("-Aandroid.databinding.classLogDir=" + class_info_path)
    javac_opts.append("-Aandroid.databinding.layoutInfoDir=" + layout_info_path)
    return javac_opts

def _process(
        ctx,
        resources_ctx = None,
        defines_resources = False,
        enable_data_binding = False,
        java_package = None,
        layout_info = None,
        artifact_type = "LIBRARY",
        deps = [],
        exports = [],
        data_binding_exec = None,
        data_binding_annotation_processor = None,
        data_binding_annotation_template = None):
    """Processes Android Data Binding.

    Args:
      ctx: The context.
      resources_ctx: The Android Resources context.
      defines_resources: boolean. Determines whether resources were defined.
      enable_data_binding: boolean. Determines whether Data Binding should be
        enabled.
      java_package: String. The Java package.
      layout_info: A file. The layout-info zip file.
      artifact_type: String. Either LIBRARY or APPLICATION.
      deps: sequence of DataBindingV2Info providers. A list of deps. Optional.
      exports: sequence of DataBindingV2Info providers. A list of exports.
        Optional.
      data_binding_exec: The DataBinding executable.
      data_binding_annotation_processor: JavaInfo. The JavaInfo for the
        annotation processor.
      data_binding_annotation_template: A file. Used to generate data binding
        classes.

    Returns:
      A DataBindingContextInfo provider.
    """

    if artifact_type not in ["LIBRARY", "APPLICATION"]:
        fail("Unexpected artifact type: " + artifact_type)

    # TODO(b/154513292): Clean up bad usages of context objects.
    if resources_ctx:
        defines_resources = resources_ctx.defines_resources

    # The Android Data Binding context object.
    db_info = {
        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS: [],
        _JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS: [],
        _JAVA_PLUGINS: [],
        _JAVA_SRCS: [],
        _JAVAC_OPTS: [],
        _PROVIDERS: [],
    }

    if not enable_data_binding:
        db_info[_PROVIDERS] = [
            DataBindingV2Info(
                databinding_v2_providers_in_deps = deps,
                databinding_v2_providers_in_exports = exports,
            ),
        ]
        return struct(**db_info)

    output_dir = "databinding/%s/" % ctx.label.name

    db_info[_JAVA_SRCS].append(_copy_annotation_file(
        ctx,
        output_dir,
        data_binding_annotation_template,
    ))
    db_info[_JAVA_PLUGINS].append(data_binding_annotation_processor)

    br_out = None
    setter_store_out = None
    class_info = None
    if defines_resources:
        # Outputs of the Data Binding annotation processor.
        br_out = ctx.actions.declare_file(
            output_dir + "bin-files/%s-br.bin" % java_package,
        )
        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(br_out)
        setter_store_out = ctx.actions.declare_file(
            output_dir + "bin-files/%s-setter_store.json" % java_package,
        )
        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(
            setter_store_out,
        )

        srcjar, class_info = _gen_sources(
            ctx,
            output_dir,
            java_package,
            deps,
            layout_info,
            data_binding_exec,
        )
        db_info[_JAVA_SRCS].append(srcjar)
        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(class_info)
        db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].append(
            layout_info,
        )

    dep_lib_artifacts = _setup_dependent_lib_artifacts(ctx, output_dir, deps)
    db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_INPUTS].extend(
        dep_lib_artifacts,
    )

    db_info[_JAVAC_OPTS] = _get_javac_opts(
        ctx,
        java_package,
        artifact_type,
        (
            br_out.path.rpartition(br_out.short_path)[0] +
            ctx.label.package +
            "/" +
            output_dir +
            "dependent-lib-artifacts"
        ),
        br_out.dirname,
        class_info.path if class_info else _NO_RESOURCES_PATH,
        layout_info.path if layout_info else _NO_RESOURCES_PATH,
        deps,
    )

    db_info[_PROVIDERS] = [
        DataBindingV2Info(
            setter_store_file = setter_store_out,
            class_info_file = class_info,
            br_file = br_out,
            label = str(ctx.label),
            java_package = java_package,
            databinding_v2_providers_in_deps = deps,
            databinding_v2_providers_in_exports = exports,
        ),
    ]

    return DataBindingContextInfo(**db_info)

data_binding = struct(
    process = _process,
)
