# 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.
load(
    "//kotlin/internal:defs.bzl",
    _KT_COMPILER_REPO = "KT_COMPILER_REPO",
    _KtJsInfo = "KtJsInfo",
    _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
)
load(
    "//kotlin/internal/utils:utils.bzl",
    _utils = "utils",
)

# The following kt-js flags are currently not used.
# -Xfriend-modules=<path>
#  -output-postfix <path>     Path to file which will be added to the end of output file
#  -output-prefix <path>      Path to file which will be added to the beginning of output file
#  -source-map-base-dirs <path> Base directories which are used to calculate relative paths to source files in source map
#  -source-map-embed-sources { always, never, inlining }
#                             Embed source files into source map
#  -source-map-prefix         Prefix for paths in a source map
#  -Xtyped-arrays

def kt_js_library_impl(ctx):
    toolchain = ctx.toolchains[_TOOLCHAIN_TYPE]

    # meta.js is merged in with the js in the builder. It is declared as it's created at the package level and not in
    # some anonymous directory.
    out_meta = ctx.actions.declare_file(ctx.attr.name + ".meta.js")

    # The Kotlin compiler and intellij infrastructure uses jars and bytecode. The out dir contains bytecode generated by
    # the kotlin compiler. In addition to the js and js.map file a jar is also produced.
    out_dir = ctx.actions.declare_directory(ctx.label.name)

    libraries = depset([d[_KtJsInfo].jar for d in ctx.attr.deps])

    args = _utils.init_args(
        ctx,
        "kt_js_library",
        _utils.derive_module_name(ctx),
    )

    args.add_all(
        "--kotlin_js_passthrough_flags",
        [
            "-source-map",
            "-meta-info",
            "-no-stdlib",  # TODO remove this once the stdlib is not conveyed to node via the deps attribute.
            "-module-kind",
            ctx.attr.module_kind,
            "-target",
            ctx.attr.js_target,
        ],
    )

    args.add("--output", ctx.outputs.js)
    args.add("--kotlin_js_dir", out_dir)  # TODO
    args.add("--kotlin_output_js_jar", ctx.outputs.jar)
    args.add("--kotlin_output_srcjar", ctx.outputs.srcjar)

    args.add_all("--kotlin_js_libraries", libraries, omit_if_empty = False)
    args.add_all("--sources", ctx.files.srcs)

    inputs, _, input_manifests = ctx.resolve_command(tools = [toolchain.kotlinbuilder, toolchain.kotlin_home])

    ctx.actions.run(
        mnemonic = "KotlinCompile",
        inputs = depset(inputs) + libraries + ctx.files.srcs,
        outputs = [
            ctx.outputs.js,
            ctx.outputs.js_map,
            ctx.outputs.jar,
            ctx.outputs.srcjar,
            out_meta,
            out_dir,
        ],
        executable = toolchain.kotlinbuilder.files_to_run.executable,
        execution_requirements = {"supports-workers": "1"},
        arguments = [args],
        progress_message = "Compiling Kotlin to JS %s { kt: %d }" % (ctx.label, len(ctx.files.srcs)),
        input_manifests = input_manifests,
    )

    return [
        DefaultInfo(
            files = depset([ctx.outputs.js, ctx.outputs.js_map]),
        ),
        _KtJsInfo(
            js = ctx.outputs.js,
            js_map = ctx.outputs.js_map,
            jar = ctx.outputs.jar,
            srcjar = ctx.outputs.srcjar,
        ),
    ]

def kt_js_import_impl(ctx):
    if len(ctx.files.jars) != 1:
        fail("a single jar should be supplied, multiple jars not supported")
    jar_file = ctx.files.jars[0]

    # Lock the jar name to the label name -- only make an exception for the compiler repo.
    if not (ctx.label.workspace_root.startswith("external/") and ctx.label.workspace_root.endswith(_KT_COMPILER_REPO)):
        expected_basename = "%s.jar" % ctx.label.name
        if not jar_file.basename == expected_basename:
            fail("label name %s is not the same as the jar name %s" % (jar_file.basename, expected_basename))

    args = ctx.actions.args()
    args.add("--jar", jar_file)
    args.add("--out", ctx.outputs.js)
    args.add("--aux", ctx.outputs.js_map)

    inputs, _, input_manifest = ctx.resolve_command(tools = [ctx.attr._importer])
    ctx.actions.run(
        inputs = inputs + [jar_file],
        executable = ctx.executable._importer,
        outputs = [
            ctx.outputs.js,
            ctx.outputs.js_map,
        ],
        arguments = [args],
        input_manifests = input_manifest,
    )

    return [
        DefaultInfo(
            files = depset([ctx.outputs.js, ctx.outputs.js_map]),
        ),
        _KtJsInfo(
            js = ctx.outputs.js,
            js_map = ctx.outputs.js_map,
            jar = jar_file,
            srcjar = ctx.files.srcjar[0],
        ),
    ]
