# 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.

"""
'jvm_import_external' offers additional functionality above what maven_jar has to offer.
In addition to downloading the jars, it allows to define this jar's dependencies.
thus it enables the explicit definition of the entire transitive dependency graph.

The rule achieves this by writing 'import' build rules in BUILD files next to the downloaded jars.
The name of the underlying 'import' rule needs to be specified.
An optional 'load' statement can also be provided, along with any other relevant custom attribute.
These import rules must have the following attributes:
- "jars"
- "deps"
- "runtime_deps"
- "exports"

the following macros are defined below that utilize jvm_import_external:

- jvm_maven_import_external - offers a 'maven' like api for identifying jars using 'artifact' format
- java_import_external - uses `java_import` as the underlying build rule
"""

_HEADER = "# DO NOT EDIT: generated by jvm_import_external()"

_PASS_PROPS = (
    "neverlink",
    "testonly_",
    "visibility",
    "exports",
    "runtime_deps",
    "deps",
    "tags",
)

def _jvm_import_external(repository_ctx):
    """Implementation of `java_import_external` rule."""
    if (repository_ctx.attr.generated_linkable_rule_name and
        not repository_ctx.attr.neverlink):
        fail("Only use generated_linkable_rule_name if neverlink is set")
    name = repository_ctx.attr.generated_rule_name or repository_ctx.name
    urls = repository_ctx.attr.artifact_urls
    sha = repository_ctx.attr.artifact_sha256
    extension = repository_ctx.attr.rule_metadata["extension"]
    file_extension = "." + extension
    path = repository_ctx.name + file_extension
    for url in urls:
        if url.endswith(file_extension):
            path = url[url.rindex("/") + 1:]
            break
    srcurls = repository_ctx.attr.srcjar_urls
    srcsha = repository_ctx.attr.srcjar_sha256
    srcpath = repository_ctx.name + "-src.jar" if srcurls else ""
    for url in srcurls:
        if url.endswith(file_extension):
            srcpath = url[url.rindex("/") + 1:].replace("-sources.jar", "-src.jar")
            break
    lines = [_HEADER, ""]
    if repository_ctx.attr.rule_load:
        lines.append(repository_ctx.attr.rule_load)
        lines.append("")
    if repository_ctx.attr.default_visibility:
        lines.append("package(default_visibility = %s)" % (
            repository_ctx.attr.default_visibility
        ))
        lines.append("")
    lines.append("licenses(%s)" % repr(repository_ctx.attr.licenses))
    lines.append("")
    lines.extend(_serialize_given_rule_import(
        name = name,
        additional_rule_attrs = repository_ctx.attr.additional_rule_attrs,
        attrs = repository_ctx.attr,
        import_attr = repository_ctx.attr.rule_metadata["import_attr"],
        path = path,
        props = _PASS_PROPS,
        rule_name = repository_ctx.attr.rule_name,
        srcpath = srcpath,
    ))
    if (repository_ctx.attr.neverlink and
        repository_ctx.attr.generated_linkable_rule_name):
        lines.extend(_serialize_given_rule_import(
            name = repository_ctx.attr.generated_linkable_rule_name,
            additional_rule_attrs = repository_ctx.attr.additional_rule_attrs,
            attrs = repository_ctx.attr,
            import_attr = repository_ctx.attr.rule_metadata["import_attr"],
            path = path,
            props = [p for p in _PASS_PROPS if p != "neverlink"],
            rule_name = repository_ctx.attr.rule_name,
            srcpath = srcpath,
        ))
    extra = repository_ctx.attr.extra_build_file_content
    if extra:
        lines.append(extra)
        if not extra.endswith("\n"):
            lines.append("")
    repository_ctx.download(urls, path, sha)
    if srcurls:
        repository_ctx.download(srcurls, srcpath, srcsha)
    repository_ctx.file("BUILD", "\n".join(lines))
    repository_ctx.file("%s/BUILD" % extension, "\n".join([
        _HEADER,
        "",
        "package(default_visibility = %r)" % (
            repository_ctx.attr.visibility or
            repository_ctx.attr.default_visibility
        ),
        "",
        "alias(",
        "    name = \"%s\"," % extension,
        "    actual = \"@%s\"," % repository_ctx.name,
        ")",
        "",
    ]))

# This method is public for usage in android.bzl macros
def convert_artifact_coordinate_to_urls(artifact, server_urls, packaging):
    """This function converts a Maven artifact coordinate into URLs."""

    parts = artifact.split(":")
    group_id_part = parts[0].replace(".", "/")
    artifact_id = parts[1]
    version = parts[2]
    classifier_part = ""
    if len(parts) == 4:
        packaging = parts[2]
        version = parts[3]
    elif len(parts) == 5:
        packaging = parts[2]
        classifier_part = "-" + parts[3]
        version = parts[4]

    final_name = artifact_id + "-" + version + classifier_part + "." + packaging
    url_suffix = group_id_part + "/" + artifact_id + "/" + version + "/" + final_name
    urls = []
    for server_url in server_urls:
        urls.append(_concat_with_needed_slash(server_url, url_suffix))
    return urls

def _concat_with_needed_slash(server_url, url_suffix):
    if server_url.endswith("/"):
        return server_url + url_suffix
    else:
        return server_url + "/" + url_suffix

def _serialize_given_rule_import(rule_name, import_attr, name, path, srcpath, attrs, props, additional_rule_attrs):
    lines = [
        "%s(" % rule_name,
        "    name = %s," % repr(name),
        "    " + import_attr % repr(path) + ",",
    ]

    if srcpath:
        lines.append("    srcjar = %s," % repr(srcpath))
    for prop in props:
        value = getattr(attrs, prop, None)
        if value:
            if prop.endswith("_"):
                prop = prop[:-1]
            lines.append("    %s = %s," % (prop, repr(value)))
    for attr_key in additional_rule_attrs:
        lines.append("    %s = %s," % (attr_key, additional_rule_attrs[attr_key]))
    lines.append(")")
    lines.append("")
    return lines

jvm_import_external = repository_rule(
    attrs = {
        "rule_name": attr.string(mandatory = True),
        "licenses": attr.string_list(
            mandatory = True,
            allow_empty = False,
        ),
        "artifact_urls": attr.string_list(
            mandatory = True,
            allow_empty = False,
        ),
        "artifact_sha256": attr.string(),
        "rule_metadata": attr.string_dict(
            default = {
                "extension": "jar",
                "import_attr": "jars = [%s]",
            },
        ),
        "rule_load": attr.string(),
        "additional_rule_attrs": attr.string_dict(),
        "srcjar_urls": attr.string_list(),
        "srcjar_sha256": attr.string(),
        "deps": attr.string_list(),
        "runtime_deps": attr.string_list(),
        "testonly_": attr.bool(),
        "exports": attr.string_list(),
        "neverlink": attr.bool(),
        "generated_rule_name": attr.string(),
        "generated_linkable_rule_name": attr.string(),
        "default_visibility": attr.string_list(default = ["//visibility:public"]),
        "extra_build_file_content": attr.string(),
    },
    implementation = _jvm_import_external,
)

def jvm_maven_import_external(artifact, server_urls, **kwargs):
    jvm_import_external(
        artifact_urls = convert_artifact_coordinate_to_urls(
            artifact,
            server_urls,
            "jar",
        ),
        **kwargs
    )
