# 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")
load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo")

_DEBUG = False

DEPS_ASPECTS = [
    module_mappings_aspect,
]

_ADDITIONAL_D_TS = attr.label_list(
    allow_files = True,
)

# 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": _ADDITIONAL_D_TS,
}

# Attributes shared by any typescript-compatible aspect.
ASPECT_ATTRIBUTES = {
    "_additional_d_ts": _ADDITIONAL_D_TS,
}

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
    ]

    # all reachable .d.ts files from node_modules attribute (if it has a typescript provider)
    if hasattr(ctx.attr, "node_modules") and hasattr(ctx.attr.node_modules, "typescript"):
        transitive_deps_declarations += [ctx.attr.node_modules.typescript.transitive_declarations]

    # .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 _should_generate_externs(ctx):
    """Whether externs should be generated.

    If ctx has a generate_externs attribute, the value of that is returned.
    Otherwise, this is true."""
    return getattr(ctx.attr, "generate_externs", True)

def _get_runtime(ctx):
    """Gets the runtime for the rule.

    Defaults to "browser" if the runtime attr isn't present."""
    return getattr(ctx.attr, "runtime", "browser")

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")]

        # Temporary until all imports of ngfactory/ngsummary files are removed
        # TODO(alexeagle): clean up after Ivy launch
        if getattr(ctx, "compile_angular_templates", False):
            closure_js_files += [ctx.actions.declare_file(basename + ".ngfactory.closure.js")]
            closure_js_files += [ctx.actions.declare_file(basename + ".ngsummary.closure.js")]

        if not is_dts:
            devmode_js_files += [ctx.actions.declare_file(basename + ".js")]
            declaration_files += [ctx.actions.declare_file(basename + ".d.ts")]

            # Temporary until all imports of ngfactory/ngsummary files are removed
            # TODO(alexeagle): clean up after Ivy launch
            if getattr(ctx, "compile_angular_templates", False):
                devmode_js_files += [ctx.actions.declare_file(basename + ".ngfactory.js")]
                devmode_js_files += [ctx.actions.declare_file(basename + ".ngsummary.js")]
    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,
        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.
      tsconfig: The tsconfig file to output, if other than ctx.outputs.tsconfig.
      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
    tsconfig = tsconfig if tsconfig != None else ctx.outputs.tsconfig
    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 _get_runtime(ctx) != "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 _should_generate_externs(ctx):
        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 = dep_declarations.transitive.to_list() + srcs_files
    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 = 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 = compilation_inputs + [tsconfig]
        replay_params = compile_action(
            ctx,
            inputs,
            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,
        ))
        devmode_compile_action(
            ctx,
            compilation_inputs + [tsconfig_json_es5],
            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_es6_sources = depset()
    for dep in deps:
        if hasattr(dep, "typescript"):
            transitive_es6_sources = depset(transitive = [
                transitive_es6_sources,
                dep.typescript.transitive_es6_sources,
            ])
    transitive_es6_sources = depset(transitive = [transitive_es6_sources, es6_sources])

    return {
        "providers": [
            DefaultInfo(
                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,
                ),
                files = depset(transitive = files_depsets),
            ),
            OutputGroupInfo(
                es5_sources = es5_sources,
                es6_sources = es6_sources,
            ),
            # TODO(martinprobst): Prune transitive deps, see go/dtspruning
            DeclarationInfo(
                declarations = depset(transitive = declarations_depsets),
                transitive_declarations = transitive_decls,
            ),
        ],
        "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": getattr(ctx.attr, "module_name", None),
        # Expose the tags so that a Skylark aspect can access them.
        "tags": ctx.attr.tags if hasattr(ctx.attr, "tags") else ctx.rule.attr.tags,
        "typescript": {
            # TODO(b/139705078): remove when consumers migrated to DeclarationInfo
            "declarations": depset(transitive = declarations_depsets),
            "devmode_manifest": devmode_manifest,
            "es5_sources": es5_sources,
            "es6_sources": es6_sources,
            "replay_params": replay_params,
            # TODO(b/139705078): remove when consumers migrated to DeclarationInfo
            "transitive_declarations": transitive_decls,
            "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)
