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

"""Helpers for configuring the TypeScript compiler.
"""

load(":common/module_mappings.bzl", "get_module_mappings")

_DEBUG = False

def create_tsconfig(
        ctx,
        files,
        srcs,
        devmode_manifest = None,
        tsickle_externs = None,
        type_blacklisted_declarations = [],
        out_dir = None,
        disable_strict_deps = False,
        allowed_deps = depset(),
        extra_root_dirs = [],
        module_path_prefixes = None,
        module_roots = None,
        node_modules_root = None):
    """Creates an object representing the TypeScript configuration to run the compiler under Bazel.

    Args:
      ctx: the skylark execution context
      files: Labels of all TypeScript compiler inputs
      srcs: Immediate sources being compiled, as opposed to transitive deps.
      devmode_manifest: path to the manifest file to write for --target=es5
      tsickle_externs: path to write tsickle-generated externs.js.
      type_blacklisted_declarations: types declared in these files will never be
          mentioned in generated .d.ts.
      out_dir: directory for generated output. Default is ctx.bin_dir
      disable_strict_deps: whether to disable the strict deps check
      allowed_deps: the set of files that code in srcs may depend on (strict deps)
      extra_root_dirs: Extra root dirs to be passed to tsc_wrapped.
      module_path_prefixes: additional locations to resolve modules
      module_roots: standard locations to resolve modules
      node_modules_root: the node_modules root path

    Returns:
      A nested dict that corresponds to a tsconfig.json structure
    """
    if (type(files) != type([])):
        fail("expected files argument to be a list, got " + type(files))

    outdir_path = out_dir if out_dir != None else ctx.configuration.bin_dir.path

    # Callers can choose the filename for the tsconfig, but it must always live
    # in the output directory corresponding with the label where it's declared.
    tsconfig_dir = "/".join([
        p
        for p in [
            ctx.bin_dir.path,
            ctx.label.workspace_root,
            ctx.label.package,
        ] + ctx.label.name.split("/")[:-1]
        # Skip empty path segments (eg. workspace_root when in same repo)
        if p
    ])
    workspace_path = "/".join([".."] * len(tsconfig_dir.split("/")))
    if module_path_prefixes == None:
        module_path_prefixes = [
            "",
            ctx.configuration.genfiles_dir.path + "/",
            ctx.configuration.bin_dir.path + "/",
        ]
    if module_roots == None:
        base_path_mappings = ["%s/*" % p for p in [
            ".",
            ctx.configuration.genfiles_dir.path,
            ctx.configuration.bin_dir.path,
        ]]

        node_modules_mappings = []
        if (hasattr(ctx.attr, "node_modules")):
            node_modules_mappings.append("/".join([p for p in [
                node_modules_root,
                "*",
            ] if p]))

            # TypeScript needs to look up ambient types from a 'node_modules'
            # directory, but when Bazel manages the dependencies, this directory
            # isn't in the project so TypeScript won't find it.
            # We can add it to the path mapping to make this lookup work.
            # See https://github.com/bazelbuild/rules_typescript/issues/179
            node_modules_mappings.append("/".join([p for p in [
                node_modules_root,
                "@types",
                "*",
            ] if p]))

        module_roots = {
            "*": node_modules_mappings,
            ctx.workspace_name + "/*": base_path_mappings,
        }
    module_mappings = get_module_mappings(ctx.label, ctx.attr, srcs = srcs)

    # To determine the path for auto-imports, TypeScript's language service
    # considers paths in the order they appear in tsconfig.json.
    # We want explicit module mappings ("@angular/core") to take precedence over
    # the general "*" mapping (which would create "third_party/javascript/..."),
    # so we create a new hash that contains the module_mappings and insert the
    # default lookup locations at the end.
    mapped_module_roots = {}
    for name, path in module_mappings.items():
        # Each module name maps to the immediate path, to resolve "index(.d).ts",
        # or module mappings that directly point to files (like index.d.ts).
        mapped_module_roots[name] = [
            "%s%s" % (p, path.replace(".d.ts", ""))
            for p in module_path_prefixes
        ]
        if not path.endswith(".d.ts"):
            # If not just mapping to a single .d.ts file, include a path glob that
            # maps the entire module root.
            mapped_module_roots["{}/*".format(name)] = [
                "%s%s/*" % (p, path)
                for p in module_path_prefixes
            ]
    for name, path in module_roots.items():
        mapped_module_roots[name] = path

    # Options for running the TypeScript compiler under Bazel.
    # See javascript/typescript/compiler/tsc_wrapped.ts:BazelOptions.
    # Unlike compiler_options, the paths here are relative to the rootDir,
    # not the location of the tsconfig.json file.
    # @unsorted-dict-items preserve historical order for golden tests
    bazel_options = {
        "workspaceName": ctx.workspace_name,
        "target": str(ctx.label),
        "package": ctx.label.package,
        "tsickleGenerateExterns": getattr(ctx.attr, "generate_externs", True),
        "tsickleExternsPath": tsickle_externs.path if tsickle_externs else "",
        "untyped": not getattr(ctx.attr, "tsickle_typed", False),
        "typeBlackListPaths": [f.path for f in type_blacklisted_declarations],
        # This is overridden by first-party javascript/typescript/tsconfig.bzl
        "ignoreWarningPaths": [],
        "es5Mode": devmode_manifest != None,
        "manifest": devmode_manifest if devmode_manifest else "",
        # Explicitly tell the compiler which sources we're interested in (emitting
        # and type checking).
        "compilationTargetSrc": [s.path for s in srcs],
        "addDtsClutzAliases": getattr(ctx.attr, "add_dts_clutz_aliases", False),
        "typeCheckDependencies": getattr(ctx.attr, "internal_testing_type_check_dependencies", False),
        "expectedDiagnostics": getattr(ctx.attr, "expected_diagnostics", []),
    }

    if hasattr(ctx.attr, "compile_angular_templates") and ctx.attr.compile_angular_templates:
        bazel_options["compileAngularTemplates"] = True

    if disable_strict_deps:
        bazel_options["disableStrictDeps"] = disable_strict_deps
        bazel_options["allowedStrictDeps"] = []
    else:
        bazel_options["allowedStrictDeps"] = [f.path for f in allowed_deps.to_list()]

    if hasattr(ctx.attr, "module_name") and ctx.attr.module_name:
        bazel_options["moduleName"] = ctx.attr.module_name
    if hasattr(ctx.attr, "module_root") and ctx.attr.module_root:
        bazel_options["moduleRoot"] = ctx.attr.module_root

    if "TYPESCRIPT_WORKER_CACHE_SIZE_MB" in ctx.var:
        max_cache_size_mb = int(ctx.var["TYPESCRIPT_WORKER_CACHE_SIZE_MB"])
        if max_cache_size_mb < 0:
            fail("TYPESCRIPT_WORKER_CACHE_SIZE_MB set to a negative value (%d)." % max_cache_size_mb)
        bazel_options["maxCacheSizeMb"] = max_cache_size_mb

    has_node_runtime = getattr(ctx.attr, "runtime", "browser") == "nodejs"
    target_language_level = "es5" if devmode_manifest or has_node_runtime else "es2015"

    # Keep these options in sync with those in playground/playground.ts.
    # @unsorted-dict-items preserve historical order for golden tests
    compiler_options = {
        # De-sugar to this language level
        "target": target_language_level,

        # The "typescript.es5_sources" provider is expected to work
        # in both nodejs and in browsers, so we use umd in devmode.
        # NOTE: tsc-wrapped will always name the enclosed AMD modules
        # For production mode, we leave the module syntax alone and let the
        # bundler handle it (including dynamic import).
        # Note, in google3 we override this option with "commonjs" since Tsickle
        # will convert that to goog.module syntax.
        "module": "umd" if devmode_manifest or has_node_runtime else "esnext",

        # Has no effect in closure/ES2015 mode. Always true just for simplicity.
        "downlevelIteration": True,

        # Do not type-check the lib.*.d.ts.
        # We think this shouldn't be necessary but haven't figured out why yet
        # and builds are faster with the setting on.
        # See http://b/30709121
        "skipDefaultLibCheck": True,
        "moduleResolution": "node",
        "outDir": "/".join([workspace_path, outdir_path]),

        # We must set a rootDir to avoid TypeScript emit paths varying
        # due computeCommonSourceDirectory behavior.
        # TypeScript requires the rootDir be a parent of all sources in
        # files[], so it must be set to the workspace_path.
        "rootDir": workspace_path,

        # Path handling for resolving modules, see specification at
        # https://github.com/Microsoft/TypeScript/issues/5039
        # Paths where we attempt to load relative references.
        # Longest match wins
        #
        # tsc_wrapped also uses this property to strip leading paths
        # to produce a flattened output tree, see
        # https://github.com/Microsoft/TypeScript/issues/8245
        "rootDirs": ["/".join([workspace_path, e]) for e in extra_root_dirs] + [
            workspace_path,
            "/".join([workspace_path, ctx.configuration.genfiles_dir.path]),
            "/".join([workspace_path, ctx.configuration.bin_dir.path]),
        ],

        # Root for non-relative module names
        "baseUrl": workspace_path,

        # "short name" mappings for npm packages, such as "@angular/core"
        "paths": mapped_module_roots,

        # Inline const enums.
        "preserveConstEnums": False,

        # permit `@Decorator` syntax and allow runtime reflection on their types.
        "experimentalDecorators": True,
        "emitDecoratorMetadata": True,

        # Interpret JSX as React calls (until someone asks for something different)
        "jsx": "react",

        # Print out full errors. By default TS truncates errors >100 chars. This can make it
        # impossible to understand some errors.
        "noErrorTruncation": True,
        # Do not emit files if they had errors (avoid accidentally serving broken code).
        "noEmitOnError": False,
        # Create .d.ts files as part of compilation.
        "declaration": True,

        # We don't support this compiler option (See github #32), so
        # always emit declaration files in the same location as outDir.
        "declarationDir": "/".join([workspace_path, outdir_path]),
        "stripInternal": True,

        # Embed source maps and sources in .js outputs
        "inlineSourceMap": True,
        "inlineSources": True,
        # Implied by inlineSourceMap: True
        "sourceMap": False,
    }

    if hasattr(ctx.attr, "node_modules"):
        compiler_options["typeRoots"] = ["/".join([p for p in [
            workspace_path,
            node_modules_root,
            "@types",
        ] if p])]

    if _DEBUG:
        compiler_options["traceResolution"] = True
        compiler_options["diagnostics"] = True

    # @unsorted-dict-items preserve historical order for golden tests
    return {
        "compilerOptions": compiler_options,
        "bazelOptions": bazel_options,
        "files": [workspace_path + "/" + f.path for f in files],
        "compileOnSave": False,
    }
