# 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 = "@npm//@bazel/typescript/bin: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.to_list()))

    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

    # Override the target so we use es2015 for devmode
    # Since g3 isn't ready to do this yet
    config["compilerOptions"]["target"] = "es2015"

    # 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,
        ),
        "compile_angular_templates": attr.bool(
            doc = """Run the Angular ngtsc compiler under ts_library""",
        ),
        "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)
