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

"TypeScript compilation"

load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "collect_node_modules_aspect")

# pylint: disable=unused-argument
# pylint: disable=missing-docstring
load(":common/compilation.bzl", "COMMON_ATTRIBUTES", "DEPS_ASPECTS", "compile_ts", "ts_providers_dict_to_struct")
load(":common/tsconfig.bzl", "create_tsconfig")
load(":ts_config.bzl", "TsConfigInfo")

_DEFAULT_COMPILER = "@build_bazel_rules_typescript//:@bazel/typescript/tsc_wrapped"

def _trim_package_node_modules(package_name):
    # trim a package name down to its path prior to a node_modules
    # segment. 'foo/node_modules/bar' would become 'foo' and
    # 'node_modules/bar' would become ''
    segments = []
    for n in package_name.split("/"):
        if n == "node_modules":
            break
        segments += [n]
    return "/".join(segments)

def _compute_node_modules_root(ctx):
    """Computes the node_modules root from the node_modules and deps attributes.

    Args:
      ctx: the skylark execution context

    Returns:
      The node_modules root as a string
    """
    node_modules_root = None
    if ctx.files.node_modules:
        # ctx.files.node_modules is not an empty list
        node_modules_root = "/".join([f for f in [
            ctx.attr.node_modules.label.workspace_root,
            _trim_package_node_modules(ctx.attr.node_modules.label.package),
            "node_modules",
        ] if f])
    for d in ctx.attr.deps:
        if NodeModuleInfo in d:
            possible_root = "/".join(["external", d[NodeModuleInfo].workspace, "node_modules"])
            if not node_modules_root:
                node_modules_root = possible_root
            elif node_modules_root != possible_root:
                fail("All npm dependencies need to come from a single workspace. Found '%s' and '%s'." % (node_modules_root, possible_root))
    if not node_modules_root:
        # there are no fine grained deps and the node_modules attribute is an empty filegroup
        # but we still need a node_modules_root even if its empty
        node_modules_root = "/".join([f for f in [
            ctx.attr.node_modules.label.workspace_root,
            ctx.attr.node_modules.label.package,
            "node_modules",
        ] if f])
    return node_modules_root

def _filter_ts_inputs(all_inputs):
    return [
        f
        for f in all_inputs
        if f.path.endswith(".js") or f.path.endswith(".ts") or f.path.endswith(".json")
    ]

def _compile_action(ctx, inputs, outputs, tsconfig_file, node_opts, description = "prodmode"):
    externs_files = []
    action_inputs = []
    action_outputs = []
    for output in outputs:
        if output.basename.endswith(".externs.js"):
            externs_files.append(output)
        elif output.basename.endswith(".es5.MF"):
            ctx.actions.write(output, content = "")
        else:
            action_outputs.append(output)

    # TODO(plf): For now we mock creation of files other than {name}.js.
    for externs_file in externs_files:
        ctx.actions.write(output = externs_file, content = "")

    # A ts_library that has only .d.ts inputs will have no outputs,
    # therefore there are no actions to execute
    if not action_outputs:
        return None

    action_inputs.extend(_filter_ts_inputs(ctx.files.node_modules))

    # Also include files from npm fine grained deps as action_inputs.
    # These deps are identified by the NodeModuleInfo provider.
    for d in ctx.attr.deps:
        if NodeModuleInfo in d:
            action_inputs.extend(_filter_ts_inputs(d.files))

    if ctx.file.tsconfig:
        action_inputs.append(ctx.file.tsconfig)
        if TsConfigInfo in ctx.attr.tsconfig:
            action_inputs.extend(ctx.attr.tsconfig[TsConfigInfo].deps)

    # Pass actual options for the node binary in the special "--node_options" argument.
    arguments = ["--node_options=%s" % opt for opt in node_opts]

    # One at-sign makes this a params-file, enabling the worker strategy.
    # Two at-signs escapes the argument so it's passed through to tsc_wrapped
    # rather than the contents getting expanded.
    if ctx.attr.supports_workers:
        arguments.append("@@" + tsconfig_file.path)
        mnemonic = "TypeScriptCompile"
    else:
        arguments.append("-p")
        arguments.append(tsconfig_file.path)
        mnemonic = "tsc"

    ctx.actions.run(
        progress_message = "Compiling TypeScript (%s) %s" % (description, ctx.label),
        mnemonic = mnemonic,
        inputs = depset(action_inputs, transitive = [inputs]),
        outputs = action_outputs,
        # Use the built-in shell environment
        # Allow for users who set a custom shell that can locate standard binaries like tr and uname
        # See https://github.com/NixOS/nixpkgs/issues/43955#issuecomment-407546331
        use_default_shell_env = True,
        arguments = arguments,
        executable = ctx.executable.compiler,
        execution_requirements = {
            "supports-workers": str(int(ctx.attr.supports_workers)),
        },
    )

    # Enable the replay_params in case an aspect needs to re-build this library.
    return struct(
        label = ctx.label,
        tsconfig = tsconfig_file,
        inputs = depset(action_inputs, transitive = [inputs]),
        outputs = action_outputs,
        compiler = ctx.executable.compiler,
    )

def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
    _compile_action(
        ctx,
        inputs,
        outputs,
        tsconfig_file,
        node_opts,
        description = "devmode",
    )

def tsc_wrapped_tsconfig(
        ctx,
        files,
        srcs,
        devmode_manifest = None,
        jsx_factory = None,
        **kwargs):
    """Produce a tsconfig.json that sets options required under Bazel.
    """

    # The location of tsconfig.json is interpreted as the root of the project
    # when it is passed to the TS compiler with the `-p` option:
    #   https://www.typescriptlang.org/docs/handbook/tsconfig-json.html.
    # Our tsconfig.json is in bazel-foo/bazel-out/local-fastbuild/bin/{package_path}
    # because it's generated in the execution phase. However, our source files are in
    # bazel-foo/ and therefore we need to strip some parent directories for each
    # f.path.

    node_modules_root = _compute_node_modules_root(ctx)
    config = create_tsconfig(
        ctx,
        files,
        srcs,
        devmode_manifest = devmode_manifest,
        node_modules_root = node_modules_root,
        **kwargs
    )
    config["bazelOptions"]["nodeModulesPrefix"] = node_modules_root

    # If the user gives a tsconfig attribute, the generated file should extend
    # from the user's tsconfig.
    # See https://github.com/Microsoft/TypeScript/issues/9876
    # We subtract the ".json" from the end before handing to TypeScript because
    # this gives extra error-checking.
    if ctx.file.tsconfig:
        workspace_path = config["compilerOptions"]["rootDir"]
        config["extends"] = "/".join([workspace_path, ctx.file.tsconfig.path[:-len(".json")]])

    if jsx_factory:
        config["compilerOptions"]["jsxFactory"] = jsx_factory

    tsetse_disabled_rules = []

    # Matches section in javascript/typescript/tsconfig.bzl
    # TODO(alexeagle): make them share code
    if ctx.label.workspace_root.startswith("external/"):
        # Violated by rxjs
        tsetse_disabled_rules += ["ban-promise-as-condition"]

        # For local testing
        tsetse_disabled_rules += ["check-return-value"]

    config["compilerOptions"]["plugins"] = [{
        "name": "@bazel/tsetse",
        "disabledRules": tsetse_disabled_rules,
    }]

    return config

# ************ #
# ts_library   #
# ************ #

def _ts_library_impl(ctx):
    """Implementation of ts_library.

    Args:
      ctx: the context.

    Returns:
      the struct returned by the call to compile_ts.
    """
    ts_providers = compile_ts(
        ctx,
        is_library = True,
        # Filter out the node_modules from deps passed to TypeScript compiler
        # since they don't have the required providers.
        # They were added to the action inputs for tsc_wrapped already.
        # strict_deps checking currently skips node_modules.
        # TODO(alexeagle): turn on strict deps checking when we have a real
        # provider for JS/DTS inputs to ts_library.
        deps = [d for d in ctx.attr.deps if not NodeModuleInfo in d],
        compile_action = _compile_action,
        devmode_compile_action = _devmode_compile_action,
        tsc_wrapped_tsconfig = tsc_wrapped_tsconfig,
    )
    return ts_providers_dict_to_struct(ts_providers)

local_deps_aspects = [collect_node_modules_aspect]

# Workaround skydoc bug which assumes DEPS_ASPECTS is a str type
[local_deps_aspects.append(a) for a in DEPS_ASPECTS]

ts_library = rule(
    _ts_library_impl,
    attrs = dict(COMMON_ATTRIBUTES, **{
        "srcs": attr.label_list(
            doc = "The TypeScript source files to compile.",
            allow_files = [".ts", ".tsx"],
            mandatory = True,
        ),
        "compiler": attr.label(
            doc = """Sets a different TypeScript compiler binary to use for this library.
            For example, we use the vanilla TypeScript tsc.js for bootstrapping,
            and Angular compilations can replace this with `ngc`.

            The default ts_library compiler depends on the `@npm//@bazel/typescript`
            target which is setup for projects that use bazel managed npm deps that
            fetch the @bazel/typescript npm package. It is recommended that you use
            the workspace name `@npm` for bazel managed deps so the default
            compiler works out of the box. Otherwise, you'll have to override
            the compiler attribute manually.
            """,
            default = Label(_DEFAULT_COMPILER),
            allow_files = True,
            executable = True,
            cfg = "host",
        ),
        "internal_testing_type_check_dependencies": attr.bool(default = False, doc = "Testing only, whether to type check inputs that aren't srcs."),
        "node_modules": attr.label(
            doc = """The npm packages which should be available during the compile.

            The default value is `@npm//typescript:typescript__typings` is setup
            for projects that use bazel managed npm deps that. It is recommended
            that you use the workspace name `@npm` for bazel managed deps so the
            default node_modules works out of the box. Otherwise, you'll have to
            override the node_modules attribute manually. This default is in place
            since ts_library will always depend on at least the typescript
            default libs which are provided by `@npm//typescript:typescript__typings`.

            This attribute is DEPRECATED. As of version 0.18.0 the recommended
            approach to npm dependencies is to use fine grained npm dependencies
            which are setup with the `yarn_install` or `npm_install` rules.

            For example, in targets that used a `//:node_modules` filegroup,

            ```
            ts_library(
              name = "my_lib",
              ...
              node_modules = "//:node_modules",
            )
            ```

            which specifies all files within the `//:node_modules` filegroup
            to be inputs to the `my_lib`. Using fine grained npm dependencies,
            `my_lib` is defined with only the npm dependencies that are
            needed:

            ```
            ts_library(
              name = "my_lib",
              ...
              deps = [
                  "@npm//@types/foo",
                  "@npm//@types/bar",
                  "@npm//foo",
                  "@npm//bar",
                  ...
              ],
            )
            ```

            In this case, only the listed npm packages and their
            transitive deps are includes as inputs to the `my_lib` target
            which reduces the time required to setup the runfiles for this
            target (see https://github.com/bazelbuild/bazel/issues/5153).
            The default typescript libs are also available via the node_modules
            default in this case.

            The @npm external repository and the fine grained npm package
            targets are setup using the `yarn_install` or `npm_install` rule
            in your WORKSPACE file:

            yarn_install(
              name = "npm",
              package_json = "//:package.json",
              yarn_lock = "//:yarn.lock",
            )
            """,
            default = Label("@npm//typescript:typescript__typings"),
        ),
        "supports_workers": attr.bool(
            doc = """Intended for internal use only.
            Allows you to disable the Bazel Worker strategy for this library.
            Typically used together with the "compiler" setting when using a
            non-worker aware compiler binary.""",
            default = True,
        ),

        # TODO(alexeagle): reconcile with google3: ts_library rules should
        # be portable across internal/external, so we need this attribute
        # internally as well.
        "tsconfig": attr.label(
            doc = """A tsconfig.json file containing settings for TypeScript compilation.
            Note that some properties in the tsconfig are governed by Bazel and will be
            overridden, such as `target` and `module`.

            The default value is set to `//:tsconfig.json` by a macro. This means you must
            either:

            - Have your `tsconfig.json` file in the workspace root directory
            - Use an alias in the root BUILD.bazel file to point to the location of tsconfig:
              `alias(name="tsconfig.json", actual="//path/to:tsconfig-something.json")`
            - Give an explicit `tsconfig` attribute to all `ts_library` targets
            """,
            allow_single_file = True,
        ),
        "tsickle_typed": attr.bool(default = True),
        "deps": attr.label_list(aspects = local_deps_aspects),
    }),
    outputs = {
        "tsconfig": "%{name}_tsconfig.json",
    },
)
"""
`ts_library` type-checks and compiles a set of TypeScript sources to JavaScript.

It produces declarations files (`.d.ts`) which are used for compiling downstream
TypeScript targets and JavaScript for the browser and Closure compiler.
"""

def ts_library_macro(tsconfig = None, **kwargs):
    """Wraps `ts_library` to set the default for the `tsconfig` attribute.

    This must be a macro so that the string is converted to a label in the context of the
    workspace that declares the `ts_library` target, rather than the workspace that defines
    `ts_library`, or the workspace where the build is taking place.

    This macro is re-exported as `ts_library` in the public API.

    Args:
      tsconfig: the label pointing to a tsconfig.json file
      **kwargs: remaining args to pass to the ts_library rule
    """
    if not tsconfig:
        tsconfig = "//:tsconfig.json"

    ts_library(tsconfig = tsconfig, **kwargs)
