# 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("//providers: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 %{output}",
        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(
        java_package,
        artifact_type,
        dependency_artifacts_dir,
        aar_out_dir,
        class_info_path,
        layout_info_path,
        deps):
    java_packages = []
    for info in deps:
        java_packages.extend(info.java_packages)

    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 _merge_lists(lists):
    merged = []
    for sublist in lists:
        merged.extend(sublist)
    return merged

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(
                setter_stores = depset(transitive = [info.setter_stores for info in exports]),
                class_infos = depset(transitive = [info.class_infos for info in exports]),
                transitive_br_files = depset(transitive =
                                                 [info.transitive_br_files for info in deps] +
                                                 [info.transitive_br_files for info in exports]),
                java_packages = _merge_lists([info.java_packages for info in 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(
        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_stores = depset(
                direct = [setter_store_out] if setter_store_out else [],
                transitive = [info.setter_stores for info in exports],
            ),
            class_infos = depset(
                direct = [class_info] if class_info else [],
                transitive = [info.class_infos for info in exports],
            ),
            transitive_br_files = depset(
                direct = [br_out] if br_out else [],
                transitive = [info.transitive_br_files for info in deps] +
                             [info.transitive_br_files for info in exports],
            ),
            java_packages = [java_package] + _merge_lists([info.java_packages for info in exports]),
        ),
    ]

    return DataBindingContextInfo(**db_info)

data_binding = struct(
    process = _process,
)
