# 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,
]

_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 {
        "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": getattr(ctx.attr, "module_name", None),
        "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 if hasattr(ctx.attr, "tags") else ctx.rule.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_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)
