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

"""Used for compilation by the different implementations of build_defs.bzl.
"""

load(":common/json_marshal.bzl", "json_marshal")
load(":common/module_mappings.bzl", "module_mappings_aspect")


_DEBUG = False

DEPS_ASPECTS = [
    module_mappings_aspect,
]

# Attributes shared by any typescript-compatible rule (ts_library, ng_module)
COMMON_ATTRIBUTES = {
    "data": attr.label_list(
        default = [],
        allow_files = True,
    ),
    # A list of diagnostics expected when compiling this library, in the form of
    # "diagnostic:regexp", e.g. "TS1234:failed to quizzle the .* wobble".
    # Useful to test for expected compilation errors.
    "expected_diagnostics": attr.string_list(),
    # Whether to generate externs.js from any "declare" statement.
    "generate_externs": attr.bool(default = True),
    # Used to determine module mappings
    "module_name": attr.string(),
    "module_root": attr.string(),
    # TODO(evanm): make this the default and remove the option.
    "runtime": attr.string(default = "browser"),
    # TODO(radokirov): remove this attr when clutz is stable enough to consume
    # any closure JS code.
    "runtime_deps": attr.label_list(
        default = [],
        providers = ["js"],
    ),
    "deps": attr.label_list(aspects = DEPS_ASPECTS),
    "_additional_d_ts": attr.label_list(
        allow_files = True,
    ),
}

COMMON_OUTPUTS = {
    # Allow the tsconfig.json to be generated without running compile actions.
    "tsconfig": "%{name}_tsconfig.json",
}

# TODO(plf): Enforce this at analysis time.
def assert_js_or_typescript_deps(ctx, deps = None):
    # `deps` args is optinal for backward compat.
    # Fallback to `ctx.attr.deps`.
    deps = deps if deps != None else ctx.attr.deps
    for dep in deps:
        if not hasattr(dep, "typescript") and not hasattr(dep, "js"):
            allowed_deps_msg = "Dependencies must be ts_library"

            fail("%s is neither a TypeScript nor a JS producing rule.\n%s\n" % (dep.label, allowed_deps_msg))

_DEPSET_TYPE = type(depset())

def _check_ts_provider(dep):
    """Verifies the type shape of the typescript provider in dep, if it has one.
    """

    # Under Bazel, some third parties have created typescript providers which may not be compatible.
    # Rather than users getting an obscure error later, explicitly check them and point to the
    # target that created the bad provider.
    # TODO(alexeagle): remove this after some transition period, maybe mid-2019
    if hasattr(dep, "typescript"):
        if type(dep.typescript.declarations) != _DEPSET_TYPE:
            fail("typescript provider in %s defined declarations as a %s rather than a depset" % (
                dep.label,
                type(dep.typescript.declarations),
            ))
        if type(dep.typescript.transitive_declarations) != _DEPSET_TYPE:
            fail("typescript provider in %s defined transitive_declarations as a %s rather than a depset" % (
                dep.label,
                type(dep.typescript.transitive_declarations),
            ))
        if type(dep.typescript.type_blacklisted_declarations) != _DEPSET_TYPE:
            fail("typescript provider in %s defined type_blacklisted_declarations as a %s rather than a depset" % (
                dep.label,
                type(dep.typescript.type_blacklisted_declarations),
            ))
    return dep

def _collect_dep_declarations(ctx, deps):
    """Collects .d.ts files from typescript and javascript dependencies.

    Args:
      ctx: ctx.
      deps: dependent targets, generally ctx.attr.deps

    Returns:
      A struct of depsets for direct, transitive and type-blacklisted declarations.
    """

    deps_and_helpers = [
        _check_ts_provider(dep)
        for dep in deps + getattr(ctx.attr, "_helpers", [])
        if hasattr(dep, "typescript")
    ]

    # .d.ts files from direct dependencies, ok for strict deps
    direct_deps_declarations = [dep.typescript.declarations for dep in deps_and_helpers]

    # all reachable .d.ts files from dependencies.
    transitive_deps_declarations = [
        dep.typescript.transitive_declarations
        for dep in deps_and_helpers
    ]

    # .d.ts files whose types tsickle will not emit (used for ts_declaration(generate_externs=False).
    type_blacklisted_declarations = [
        dep.typescript.type_blacklisted_declarations
        for dep in deps_and_helpers
    ]

    # If a tool like github.com/angular/clutz can create .d.ts from type annotated .js
    # its output will be collected here.

    return struct(
        direct = depset(transitive = direct_deps_declarations),
        transitive = depset(
            [extra for extra in ctx.files._additional_d_ts],
            transitive = transitive_deps_declarations,
        ),
        type_blacklisted = depset(transitive = type_blacklisted_declarations),
    )

def _outputs(ctx, label, srcs_files = []):
    """Returns closure js, devmode js, and .d.ts output files.

    Args:
      ctx: ctx.
      label: Label. package label.
      srcs_files: File list. sources files list.

    Returns:
      A struct of file lists for different output types.
    """
    workspace_segments = label.workspace_root.split("/") if label.workspace_root else []
    package_segments = label.package.split("/") if label.package else []
    trim = len(workspace_segments) + len(package_segments)
    create_shim_files = False

    closure_js_files = []
    devmode_js_files = []
    declaration_files = []
    for input_file in srcs_files:
        is_dts = input_file.short_path.endswith(".d.ts")
        if is_dts and not create_shim_files:
            continue
        basename = "/".join(input_file.short_path.split("/")[trim:])
        for ext in [".d.ts", ".tsx", ".ts"]:
            if basename.endswith(ext):
                basename = basename[:-len(ext)]
                break
        closure_js_files += [ctx.actions.declare_file(basename + ".closure.js")]
        if not is_dts:
            devmode_js_files += [ctx.actions.declare_file(basename + ".js")]
            declaration_files += [ctx.actions.declare_file(basename + ".d.ts")]
    return struct(
        closure_js = closure_js_files,
        devmode_js = devmode_js_files,
        declarations = declaration_files,
    )

def compile_ts(
        ctx,
        is_library,
        srcs = None,
        deps = None,
        compile_action = None,
        devmode_compile_action = None,
        jsx_factory = None,
        tsc_wrapped_tsconfig = None,
        outputs = _outputs):
    """Creates actions to compile TypeScript code.

    This rule is shared between ts_library and ts_declaration.

    Args:
      ctx: ctx.
      is_library: boolean. False if only compiling .dts files.
      srcs: label list. Explicit list of sources to be used instead of ctx.attr.srcs.
      deps: label list. Explicit list of deps to be used instead of ctx.attr.deps.
      compile_action: function. Creates the compilation action.
      devmode_compile_action: function. Creates the compilation action
        for devmode.
      jsx_factory: optional string. Enables overriding jsx pragma.
      tsc_wrapped_tsconfig: function that produces a tsconfig object.
      outputs: function from a ctx to the expected compilation outputs.

    Returns:
      struct that will be returned by the rule implementation.
    """

    ### Collect srcs and outputs.
    srcs = srcs if srcs != None else ctx.attr.srcs
    deps = deps if deps != None else ctx.attr.deps
    srcs_files = [f for t in srcs for f in t.files.to_list()]
    src_declarations = []  # d.ts found in inputs.
    tsickle_externs = []  # externs.js generated by tsickle, if any.
    has_sources = False

    # Validate the user inputs.
    assert_js_or_typescript_deps(ctx, deps)

    for src in srcs:
        if src.label.package != ctx.label.package:
            # Sources can be in sub-folders, but not in sub-packages.
            fail("Sources must be in the same package as the ts_library rule, " +
                 "but %s is not in %s" % (src.label, ctx.label.package), "srcs")
        if hasattr(src, "typescript"):
            # Guard against users accidentally putting deps into srcs by
            # rejecting all srcs values that have a TypeScript provider.
            # TS rules produce a ".d.ts" file, which is a valid input in "srcs",
            # and will then be compiled as a source .d.ts file would, creating
            # externs etc.
            fail(
                "must not reference any TypeScript rules - did you mean deps?",
                "srcs",
            )

        for f in src.files.to_list():
            has_sources = True
            if not is_library and not f.path.endswith(".d.ts"):
                fail("srcs must contain only type declarations (.d.ts files), " +
                     "but %s contains %s" % (src.label, f.short_path), "srcs")
            if f.path.endswith(".d.ts"):
                src_declarations += [f]
                continue

    outs = outputs(ctx, ctx.label, srcs_files)
    transpiled_closure_js = outs.closure_js
    transpiled_devmode_js = outs.devmode_js
    gen_declarations = outs.declarations

    if has_sources and ctx.attr.runtime != "nodejs":
        # Note: setting this variable controls whether tsickle is run at all.
        tsickle_externs = [ctx.actions.declare_file(ctx.label.name + ".externs.js")]

    dep_declarations = _collect_dep_declarations(ctx, deps)
    input_declarations = depset(src_declarations, transitive = [dep_declarations.transitive])
    type_blacklisted_declarations = dep_declarations.type_blacklisted
    if not is_library and not ctx.attr.generate_externs:
        type_blacklisted_declarations += srcs_files

    # The depsets of output files. These are the files that are always built
    # (including e.g. if you "blaze build :the_target" directly).
    files_depsets = []

    # A manifest listing the order of this rule's *.ts files (non-transitive)
    # Only generated if the rule has any sources.
    devmode_manifest = None

    # Enable to produce a performance trace when compiling TypeScript to JS.
    # The trace file location will be printed as a build result and can be read
    # in Chrome's chrome://tracing/ UI.
    perf_trace = _DEBUG
    if "TYPESCRIPT_PERF_TRACE_TARGET" in ctx.var:
        perf_trace = str(ctx.label) == ctx.var["TYPESCRIPT_PERF_TRACE_TARGET"]

    compilation_inputs = depset(srcs_files, transitive = [input_declarations])
    tsickle_externs_path = tsickle_externs[0] if tsickle_externs else None

    # Calculate allowed dependencies for strict deps enforcement.
    allowed_deps = depset(
        # A target's sources may depend on each other,
        srcs_files,
        # or on a .d.ts from a direct dependency
        transitive = [dep_declarations.direct],
    )

    tsconfig_es6 = tsc_wrapped_tsconfig(
        ctx,
        compilation_inputs,
        srcs_files,
        jsx_factory = jsx_factory,
        tsickle_externs = tsickle_externs_path,
        type_blacklisted_declarations = type_blacklisted_declarations.to_list(),
        allowed_deps = allowed_deps,
    )

    # Do not produce declarations in ES6 mode, tsickle cannot produce correct
    # .d.ts (or even errors) from the altered Closure-style JS emit.
    tsconfig_es6["compilerOptions"]["declaration"] = False
    tsconfig_es6["compilerOptions"].pop("declarationDir")
    outputs = transpiled_closure_js + tsickle_externs

    node_profile_args = []
    if perf_trace and has_sources:
        perf_trace_file = ctx.actions.declare_file(ctx.label.name + ".es6.trace")
        tsconfig_es6["bazelOptions"]["perfTracePath"] = perf_trace_file.path
        outputs.append(perf_trace_file)

        profile_file = ctx.actions.declare_file(ctx.label.name + ".es6.v8.log")
        node_profile_args = [
            "--prof",
            # Without nologfile_per_isolate, v8 embeds an
            # unpredictable hash code in the file name, which
            # doesn't work with blaze.
            "--nologfile_per_isolate",
            "--logfile=" + profile_file.path,
        ]
        outputs.append(profile_file)

        files_depsets.append(depset([perf_trace_file, profile_file]))

    ctx.actions.write(
        output = ctx.outputs.tsconfig,
        content = json_marshal(tsconfig_es6),
    )

    # Parameters of this compiler invocation in case we need to replay this with different
    # settings.
    replay_params = None

    if has_sources:
        inputs = depset([ctx.outputs.tsconfig], transitive = [compilation_inputs])
        replay_params = compile_action(
            ctx,
            inputs,
            outputs,
            ctx.outputs.tsconfig,
            node_profile_args,
        )

        devmode_manifest = ctx.actions.declare_file(ctx.label.name + ".es5.MF")
        tsconfig_json_es5 = ctx.actions.declare_file(ctx.label.name + "_es5_tsconfig.json")
        outputs = (
            transpiled_devmode_js + gen_declarations + [devmode_manifest]
        )
        tsconfig_es5 = tsc_wrapped_tsconfig(
            ctx,
            compilation_inputs,
            srcs_files,
            jsx_factory = jsx_factory,
            devmode_manifest = devmode_manifest.path,
            allowed_deps = allowed_deps,
        )
        node_profile_args = []
        if perf_trace:
            perf_trace_file = ctx.actions.declare_file(ctx.label.name + ".es5.trace")
            tsconfig_es5["bazelOptions"]["perfTracePath"] = perf_trace_file.path
            outputs.append(perf_trace_file)

            profile_file = ctx.actions.declare_file(ctx.label.name + ".es5.v8.log")
            node_profile_args = [
                "--prof",
                # Without nologfile_per_isolate, v8 embeds an
                # unpredictable hash code in the file name, which
                # doesn't work with blaze.
                "--nologfile_per_isolate",
                "--logfile=" + profile_file.path,
            ]
            outputs.append(profile_file)

            files_depsets.append(depset([perf_trace_file, profile_file]))

        ctx.actions.write(output = tsconfig_json_es5, content = json_marshal(
            tsconfig_es5,
        ))
        inputs = depset([tsconfig_json_es5], transitive = [compilation_inputs])
        devmode_compile_action(
            ctx,
            inputs,
            outputs,
            tsconfig_json_es5,
            node_profile_args,
        )

    # TODO(martinprobst): Merge the generated .d.ts files, and enforce strict
    # deps (do not re-export transitive types from the transitive closure).
    transitive_decls = depset(src_declarations + gen_declarations, transitive = [dep_declarations.transitive])

    # both ts_library and ts_declarations generate .closure.js files:
    # - for libraries, this is the ES6/production code
    # - for declarations, these are generated shims
    es6_sources = depset(transpiled_closure_js + tsickle_externs)
    if is_library:
        es5_sources = depset(transpiled_devmode_js)
    else:
        # In development mode, no code ever references shims as they only
        # contain types, and the ES5 code does not get type annotated.
        es5_sources = depset(tsickle_externs)

        # Similarly, in devmode these sources do not get loaded, so do not need
        # to be in a manifest.
        devmode_manifest = None

    # Downstream rules see the .d.ts files produced or declared by this rule.
    declarations_depsets = [depset(gen_declarations + src_declarations)]
    if not srcs_files:
        # Re-export sources from deps.
        # TODO(b/30018387): introduce an "exports" attribute.
        for dep in deps:
            if hasattr(dep, "typescript"):
                declarations_depsets.append(dep.typescript.declarations)
    files_depsets.extend(declarations_depsets)

    # If this is a ts_declaration, add tsickle_externs to the outputs list to
    # force compilation of d.ts files.  (tsickle externs are produced by running a
    # compilation over the d.ts file and extracting type information.)
    if not is_library:
        files_depsets.append(depset(tsickle_externs))

    transitive_es5_sources = depset()
    transitive_es6_sources = depset()
    for dep in deps:
        if hasattr(dep, "typescript"):
            transitive_es5_sources = depset(transitive = [
                transitive_es5_sources,
                dep.typescript.transitive_es5_sources,
            ])
            transitive_es6_sources = depset(transitive = [
                transitive_es6_sources,
                dep.typescript.transitive_es6_sources,
            ])
    transitive_es5_sources = depset(transitive = [transitive_es5_sources, es5_sources])
    transitive_es6_sources = depset(transitive = [transitive_es6_sources, es6_sources])

    return {
        "files": depset(transitive = files_depsets),
        "instrumented_files": {
            "dependency_attributes": ["deps", "runtime_deps"],
            "extensions": ["ts"],
            "source_attributes": ["srcs"],
        },
        # Expose the module_name so that packaging rules can access it.
        # e.g. rollup_bundle under Bazel needs to convert this into a UMD global
        # name in the Rollup configuration.
        "module_name": ctx.attr.module_name,
        "output_groups": {
            "es5_sources": es5_sources,
            "es6_sources": es6_sources,
        },
        "runfiles": ctx.runfiles(
            # Note: don't include files=... here, or they will *always* be built
            # by any dependent rule, regardless of whether it needs them.
            # But these attributes are needed to pass along any input runfiles:
            collect_default = True,
            collect_data = True,
        ),
        # Expose the tags so that a Skylark aspect can access them.
        "tags": ctx.attr.tags,
        # TODO(martinprobst): Prune transitive deps, only re-export what's needed.
        "typescript": {
            "declarations": depset(transitive = declarations_depsets),
            "devmode_manifest": devmode_manifest,
            "es5_sources": es5_sources,
            "es6_sources": es6_sources,
            "replay_params": replay_params,
            "transitive_declarations": transitive_decls,
            "transitive_es5_sources": transitive_es5_sources,
            "transitive_es6_sources": transitive_es6_sources,
            "tsickle_externs": tsickle_externs,
            "type_blacklisted_declarations": type_blacklisted_declarations,
        },
    }

# Converts a dict to a struct, recursing into a single level of nested dicts.
# This allows users of compile_ts to modify or augment the returned dict before
# converting it to an immutable struct.
def ts_providers_dict_to_struct(d):
    for key, value in d.items():
        if key != "output_groups" and type(value) == type({}):
            d[key] = struct(**value)
    return struct(**d)
