# 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:kt.bzl", "kt")
load("//kotlin/internal:plugins.bzl", "plugins")
load("//kotlin/internal:utils.bzl", "utils")

def _declare_output_directory(ctx, aspect, dir_name):
    return ctx.actions.declare_directory("_kotlinc/%s_%s/%s_%s" % (ctx.label.name, aspect, ctx.label.name, dir_name))

def _kotlin_do_compile_action(ctx, rule_kind, output_jar, compile_jars, module_name, friend_paths, srcs, src_jars):
    """Internal macro that sets up a Kotlin compile action.

    This macro only supports a single Kotlin compile operation for a rule.

    Args:
      rule_kind: The rule kind,
      output_jar: The jar file that this macro will use as the output of the action.
      compile_jars: The compile time jars provided on the classpath for the compile operations -- callers are
        responsible for preparing the classpath. The stdlib (and jdk7 + jdk8) should generally be added to the classpath
        by the caller -- kotlin-reflect could be optional.
    """
    classes_directory=_declare_output_directory(ctx, "jvm", "classes")
    generated_classes_directory=_declare_output_directory(ctx, "jvm", "generated_classes")
    sourcegen_directory=_declare_output_directory(ctx, "jvm", "sourcegenfiles")
    temp_directory=_declare_output_directory(ctx, "jvm", "temp")


    tc=ctx.toolchains[kt.defs.TOOLCHAIN_TYPE]

    args = [
        "--target_label", ctx.label,
        "--rule_kind", rule_kind,

        "--classdir", classes_directory.path,
        "--sourcegendir", sourcegen_directory.path,
        "--tempdir", temp_directory.path,
        "--kotlin_generated_classdir", generated_classes_directory.path,

        "--output", output_jar.path,
        "--output_jdeps", ctx.outputs.jdeps.path,
        "--classpath", "\n".join([f.path for f in compile_jars.to_list()]),
        "--kotlin_friend_paths", "\n".join(friend_paths.to_list()),
        "--kotlin_jvm_target", tc.jvm_target,
        "--kotlin_api_version", tc.api_version,
        "--kotlin_language_version", tc.language_version,
        "--kotlin_module_name", module_name,
        "--kotlin_passthrough_flags", "-Xcoroutines=%s" % tc.coroutines
    ]

    if len(srcs) == 0 and len(src_jars) == 0:
        fail("srcs did not contain kotlin/java files or any srcjars")

    if len(srcs) > 0:
        args += ["--sources", "\n".join(srcs)]

    if len(src_jars) > 0:
        args += ["--source_jars", "\n".join([sj.path for sj in src_jars])]

    # Collect and prepare plugin descriptor for the worker.
    plugin_info=plugins.merge_plugin_infos(ctx.attr.plugins + ctx.attr.deps)
    if len(plugin_info.annotation_processors) > 0:
        args += [ "--kt-plugins", plugin_info.to_json() ]

    # Declare and write out argument file.
    args_file = ctx.actions.declare_file(ctx.label.name + ".jar-2.params")
    ctx.actions.write(args_file, "\n".join(args))

    # When a stratetegy isn't provided for the worker and the workspace is fresh then certain deps are not available under
    # external/@com_github_jetbrains_kotlin/... that is why the classpath is added explicetly.
    compile_inputs = (
      depset([args_file]) +
      ctx.files.srcs +
      compile_jars +
      ctx.files._kotlin_compiler_classpath +
      ctx.files._kotlin_home +
      ctx.files._jdk)

    ctx.action(
        mnemonic = "KotlinCompile",
        inputs = compile_inputs,
        outputs = [
            output_jar,
            ctx.outputs.jdeps,
            sourcegen_directory,
            classes_directory,
            temp_directory,
            generated_classes_directory
        ],
        executable = ctx.executable._kotlinw,
        execution_requirements = {"supports-workers": "1"},
        arguments = ["@" + args_file.path],
        progress_message="Compiling %d Kotlin source files to %s" % (len(ctx.files.srcs), output_jar.short_path),
    )

def _select_std_libs(ctx):
    return ctx.files._kotlin_std

def _make_java_provider(ctx, input_deps=[], auto_deps=[], src_jars=[]):
    """Creates the java_provider for a Kotlin target.

    This macro is distinct from the kotlin_make_providers as collecting the java_info is useful before the DefaultInfo is
    created.

    Args:
    ctx: The ctx of the rule in scope when this macro is called. The macro will pick up the following entities from
      the rule ctx:
        * The default output jar.
        * The `deps` for this provider.
        * Optionally `exports` (see java rules).
        * The `_kotlin_runtime` implicit dependency.
    Returns:
    A JavaInfo provider.
    """
    deps=utils.collect_all_jars(input_deps)
    exported_deps=utils.collect_all_jars(getattr(ctx.attr, "exports", []))

    my_compile_jars = exported_deps.compile_jars + [ctx.outputs.jar]
    my_runtime_jars = exported_deps.transitive_runtime_jars + [ctx.outputs.jar]

    my_transitive_compile_jars = my_compile_jars + deps.transitive_compile_time_jars + exported_deps.transitive_compile_time_jars + auto_deps
    my_transitive_runtime_jars = my_runtime_jars + deps.transitive_runtime_jars + exported_deps.transitive_runtime_jars + [ctx.file._kotlin_runtime] + auto_deps

    # collect the runtime jars from the runtime_deps attribute.
    for jar in ctx.attr.runtime_deps:
        my_transitive_runtime_jars += jar[JavaInfo].transitive_runtime_jars

    return java_common.create_provider(
        use_ijar = False,
        # A list or set of output source jars that contain the uncompiled source files including the source files
        # generated by annotation processors if the case.
        source_jars= src_jars + utils.actions.maybe_make_srcsjar(ctx),
        # A list or a set of jars that should be used at compilation for a given target.
        compile_time_jars = my_compile_jars,
        # A list or a set of jars that should be used at runtime for a given target.
        runtime_jars=my_runtime_jars,
        transitive_compile_time_jars= my_transitive_compile_jars,
        transitive_runtime_jars=my_transitive_runtime_jars
    )

def _make_providers(ctx, java_info, module_name, transitive_files=depset(order="default")):
    kotlin_info=kt.info.KtInfo(
        srcs=ctx.files.srcs,
        module_name = module_name,
        # intelij aspect needs this.
        outputs = struct(
            jdeps = ctx.outputs.jdeps,
            jars = [struct(
              class_jar = ctx.outputs.jar,
              ijar = None,
              source_jars = java_info.source_jars
            )]
        ),
    )

    default_info = DefaultInfo(
        files=depset([ctx.outputs.jar]),
        runfiles=ctx.runfiles(
            transitive_files=transitive_files,
            collect_default=True
        ),
    )

    return struct(
        kt=kotlin_info,
        providers=[java_info,default_info,kotlin_info],
    )

def _compile_action(ctx, rule_kind, module_name, friend_paths=depset(), src_jars=[]):
    """Setup a kotlin compile action.

    Args:
        ctx: The rule context.
    Returns:
        A JavaInfo struct for the output jar that this macro will build.
    """
    # The main output jars
    output_jar = ctx.outputs.jar

    # The output of the compile step may be combined (folded) with other entities -- e.g., other class files from annotation processing, embedded resources.
    kt_compile_output_jar=output_jar
    # the list of jars to merge into the final output, start with the resource jars if any were provided.
    output_merge_list=ctx.files.resource_jars

    # If this rule has any resources declared setup a zipper action to turn them into a jar and then add the declared zipper output to the merge list.
    if len(ctx.files.resources) > 0:
        output_merge_list = output_merge_list + [utils.actions.build_resourcejar(ctx)]

    # If this compile operation requires merging other jars setup the compile operation to go to a intermediate file and add that file to the merge list.
    if len(output_merge_list) > 0:
        # Intermediate jar containing the Kotlin compile output.
        kt_compile_output_jar=ctx.new_file(ctx.label.name + "-ktclass.jar")
        # If we setup indirection than the first entry in the merge list is the result of the kotlin compile action.
        output_merge_list=[ kt_compile_output_jar ] + output_merge_list

    kotlin_auto_deps=_select_std_libs(ctx)

    deps = ctx.attr.deps + getattr(ctx.attr, "friends", [])

    srcs = []
    src_jars = []
    for f in ctx.files.srcs:
        if f.path.endswith(".kt") or f.path.endswith(".java"):
            srcs.append(f.path)
        elif f.path.endswith(".srcjar"):
            src_jars.append(f)

    # setup the compile action.
    _kotlin_do_compile_action(
        ctx,
        rule_kind = rule_kind,
        output_jar = kt_compile_output_jar,
        compile_jars = utils.collect_jars_for_compile(deps) + kotlin_auto_deps,
        module_name = module_name,
        friend_paths = friend_paths,
        srcs = srcs,
        src_jars = src_jars
    )

    # setup the merge action if needed.
    if len(output_merge_list) > 0:
        utils.actions.fold_jars(ctx, output_jar, output_merge_list)

    # create the java provider but the kotlin and default provider cannot be created here.
    return _make_java_provider(ctx, deps, kotlin_auto_deps, src_jars)

compile = struct(
    compile_action = _compile_action,
    make_providers = _make_providers,
)
