# 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/module_mappings.bzl", "module_mappings_aspect")
load(":common/json_marshal.bzl", "json_marshal")

BASE_ATTRIBUTES = dict()

_DEBUG = False

DEPS_ASPECTS = [
    module_mappings_aspect,
]

# Attributes shared by any typescript-compatible rule (ts_library, ng_module)
COMMON_ATTRIBUTES = dict(BASE_ATTRIBUTES, **{
    "deps": attr.label_list(aspects = DEPS_ASPECTS),
    "data": attr.label_list(
        default = [],
        allow_files = True,
    ),
    # TODO(evanm): make this the default and remove the option.
    "runtime": attr.string(default = "browser"),
    # Used to determine module mappings
    "module_name": attr.string(),
    "module_root": attr.string(),
    # TODO(radokirov): remove this attr when clutz is stable enough to consume
    # any closure JS code.
    "runtime_deps": attr.label_list(
        default = [],
        providers = ["js"],
    ),
    "_additional_d_ts": attr.label_list(
        allow_files = True,
    ),
    # Whether to generate externs.js from any "declare" statement.
    "generate_externs": attr.bool(default = 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(),
})

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]
    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:
            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 = dep_declarations.transitive + src_declarations
    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 = input_declarations + 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,
        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 = compilation_inputs + [ctx.outputs.tsconfig]
        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 = compilation_inputs + [tsconfig_json_es5]
        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 = dep_declarations.transitive + src_declarations + gen_declarations

    # 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),
        "output_groups": {
            "es6_sources": es6_sources,
            "es5_sources": es5_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,
        ),
        # TODO(martinprobst): Prune transitive deps, only re-export what's needed.
        "typescript": {
            "declarations": depset(transitive = declarations_depsets),
            "transitive_declarations": transitive_decls,
            "es6_sources": es6_sources,
            "transitive_es6_sources": transitive_es6_sources,
            "es5_sources": es5_sources,
            "transitive_es5_sources": transitive_es5_sources,
            "devmode_manifest": devmode_manifest,
            "type_blacklisted_declarations": type_blacklisted_declarations,
            "tsickle_externs": tsickle_externs,
            "replay_params": replay_params,
        },
        # Expose the tags so that a Skylark aspect can access them.
        "tags": ctx.attr.tags,
        # 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,
        "instrumented_files": {
            "extensions": ["ts"],
            "source_attributes": ["srcs"],
            "dependency_attributes": ["deps", "runtime_deps"],
        },
    }

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