/**
 * @license
 * 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.
 */

import * as path from 'path';
import * as ts from 'typescript';

/**
 * The configuration block provided by the tsconfig "bazelOptions".
 * Note that all paths here are relative to the rootDir, not absolute nor
 * relative to the location containing the tsconfig file.
 */
export interface BazelOptions {
  /** Name of the bazel workspace where we are building. */
  workspaceName: string;

  /** The full bazel target that is being built, e.g. //my/pkg:library. */
  target: string;

  /** The bazel package, eg my/pkg */
  package: string;

  /** If true, convert require()s into goog.module(). */
  googmodule: boolean;

  /**
   * If true, emit devmode output into filename.js.
   * If false, emit prodmode output into filename.closure.js.
   */
  es5Mode: boolean;

  /** If true, convert TypeScript code into a Closure-compatible variant. */
  tsickle: boolean;

  /** If true, generate externs from declarations in d.ts files. */
  tsickleGenerateExterns: boolean;

  /** Write generated externs to the given path. */
  tsickleExternsPath: string;

  /** Paths of declarations whose types must not appear in result .d.ts. */
  typeBlackListPaths: string[];

  /** If true, emit Closure types in TypeScript->JS output. */
  untyped: boolean;

  /** The list of sources we're interested in (emitting and type checking). */
  compilationTargetSrc: string[];

  /** Path to write the module dependency manifest to. */
  manifest: string;

  /**
   * Whether to disable strict deps check. If true the next parameter is
   * ignored.
   */
  disableStrictDeps?: boolean;

  /**
   * Paths of dependencies that are allowed by strict deps, i.e. that may be
   * imported by the source files in compilationTargetSrc.
   */
  allowedStrictDeps: string[];

  /** Write a performance trace to this path. Disabled when falsy. */
  perfTracePath?: string;

  /**
   * An additional prelude to insert after the `goog.module` call,
   * e.g. with additional imports or requires.
   */
  prelude: string;

  /**
   * Name of the current locale if processing a locale-specific file.
   */
  locale?: string;

  /**
   * A list of errors this compilation is expected to generate, in the form
   * "TS1234:regexp". If empty, compilation is expected to succeed.
   */
  expectedDiagnostics: string[];

  /**
   * To support node_module resolution, allow TypeScript to make arbitrary
   * file system access to paths under this prefix.
   */
  nodeModulesPrefix: string;

  /**
   * List of regexes on file paths for which we suppress tsickle's warnings.
   */
  ignoreWarningPaths: string[];

  /**
   * Whether to add aliases to the .d.ts files to add the exports to the
   * ಠ_ಠ.clutz namespace.
   */
  addDtsClutzAliases: true;

  /**
   * Whether to type check inputs that aren't srcs.  Differs from
   * --skipLibCheck, which skips all .d.ts files, even those which are
   * srcs.
   */
  typeCheckDependencies: boolean;

  /**
   * The maximum cache size for bazel outputs, in megabytes.
   */
  maxCacheSizeMb?: number;

  /**
   * Suppress warnings about tsconfig.json properties that are overridden.
   */
  suppressTsconfigOverrideWarnings: boolean;

  /**
   * An explicit name for this module, given by the module_name attribute on a
   * ts_library.
   */
  moduleName?: string;

  /**
   * An explicit entry point for this module, given by the module_root attribute
   * on a ts_library.
   */
  moduleRoot?: string;

  /**
   * If true, indicates that this job is transpiling JS sources. If true, only
   * one file can appear in compilationTargetSrc, and transpiledJsOutputFileName
   * must be set.
   */
  isJsTranspilation?: boolean;

  /**
   * The path where the file containing the JS transpiled output should
   * be written. Ignored if isJsTranspilation is false.
   */
  transpiledJsOutputFileName?: string;

  /**
   * Whether the user provided an implementation shim for .d.ts files in the
   * compilation unit.
   */
  hasImplementation?: boolean;

  /**
   * Enable the Angular ngtsc plugin.
   */
  compileAngularTemplates?: boolean;

  /**
   * Override for ECMAScript target language level to use for devmode.
   *
   * This setting can be set in a user's tsconfig to override the default
   * devmode target.
   *
   * EXPERIMENTAL: This setting is experimental and may be removed in the
   * future.
   */
  devmodeTargetOverride?: string;
}

export interface ParsedTsConfig {
  options: ts.CompilerOptions;
  bazelOpts: BazelOptions;
  angularCompilerOptions?: {[k: string]: unknown};
  files: string[];
  disabledTsetseRules: string[];
  config: {};
}

// TODO(calebegg): Upstream?
interface PluginImportWithConfig extends ts.PluginImport {
  [optionName: string]: string|{};
}

/**
 * Prints messages to stderr if the given config object contains certain known
 * properties that Bazel will override in the generated tsconfig.json.
 * Note that this is not an exhaustive list of such properties; just the ones
 * thought to commonly cause problems.
 * Note that we can't error out, because users might have a legitimate reason:
 * - during a transition to Bazel they can use the same tsconfig with other
 *   tools
 * - if they have multiple packages in their repo, they might need to use path
 *   mapping so the editor knows where to resolve some absolute imports
 *
 * @param userConfig the parsed json for the full tsconfig.json file
 */
function warnOnOverriddenOptions(userConfig: any) {
  const overrideWarnings: string[] = [];
  if (userConfig.files) {
    overrideWarnings.push(
        'files is ignored because it is controlled by the srcs[] attribute');
  }
  const options: ts.CompilerOptions = userConfig.compilerOptions;
  if (options) {
    if (options.target || options.module) {
      overrideWarnings.push(
          'compilerOptions.target and compilerOptions.module are controlled by downstream dependencies, such as ts_devserver');
    }
    if (options.declaration) {
      overrideWarnings.push(
          `compilerOptions.declaration is always true, as it's needed for dependent libraries to type-check`);
    }
    if (options.paths) {
      overrideWarnings.push(
          'compilerOptions.paths is determined by the module_name attribute in transitive deps[]');
    }
    if (options.typeRoots) {
      overrideWarnings.push(
          'compilerOptions.typeRoots is always set to the @types subdirectory of the node_modules attribute');
    }
    if (options.traceResolution || (options as any).diagnostics) {
      overrideWarnings.push(
          'compilerOptions.traceResolution and compilerOptions.diagnostics are set by the DEBUG flag in tsconfig.bzl under rules_typescript');
    }
    if (options.rootDir || options.baseUrl) {
      overrideWarnings.push(
          'compilerOptions.rootDir and compilerOptions.baseUrl are always the workspace root directory');
    }
    if (options.preserveConstEnums) {
      overrideWarnings.push(
          'compilerOptions.preserveConstEnums is always false under Bazel');
    }
    if (options.noEmitOnError) {
      // TODO(alexeagle): why??
      overrideWarnings.push(
          'compilerOptions.noEmitOnError is always false under Bazel');
    }
  }
  if (overrideWarnings.length) {
    console.error(
        '\nWARNING: your tsconfig.json file specifies options which are overridden by Bazel:');
    for (const w of overrideWarnings) console.error(` - ${w}`);
    console.error('\n');
  }
}

/**
 * The same as Node's path.resolve, however it returns a path with forward
 * slashes rather than joining the resolved path with the platform's path
 * separator.
 * Note that even path.posix.resolve('.') returns C:\Users\... with backslashes.
 */
export function resolveNormalizedPath(...segments: string[]): string {
  return path.resolve(...segments).replace(/\\/g, '/');
}

/**
 * Load a tsconfig.json and convert all referenced paths (including
 * bazelOptions) to absolute paths.
 * Paths seen by TypeScript should be absolute, to match behavior
 * of the tsc ModuleResolution implementation.
 * @param tsconfigFile path to tsconfig, relative to process.cwd() or absolute
 * @return configuration parsed from the file, or error diagnostics
 */
export function parseTsconfig(
    tsconfigFile: string, host: ts.ParseConfigHost = ts.sys):
    [ParsedTsConfig|null, ts.Diagnostic[]|null, {target: string}] {
  // TypeScript expects an absolute path for the tsconfig.json file
  tsconfigFile = resolveNormalizedPath(tsconfigFile);

  const {config, error} = ts.readConfigFile(tsconfigFile, host.readFile);
  if (error) {
    // target is in the config file we failed to load...
    return [null, [error], {target: ''}];
  }

  // Handle bazel specific options, but make sure not to crash when reading a
  // vanilla tsconfig.json.
  const bazelOpts: BazelOptions = config.bazelOptions || {};
  const target = bazelOpts.target;
  bazelOpts.allowedStrictDeps = bazelOpts.allowedStrictDeps || [];
  bazelOpts.typeBlackListPaths = bazelOpts.typeBlackListPaths || [];
  bazelOpts.compilationTargetSrc = bazelOpts.compilationTargetSrc || [];

  // Allow Bazel users to control some of the bazel options.
  // Since TypeScript's "extends" mechanism applies only to "compilerOptions"
  // we have to repeat some of their logic to get the user's bazelOptions.
  if (config.extends) {
    let userConfigFile =
        resolveNormalizedPath(path.dirname(tsconfigFile), config.extends);
    if (!userConfigFile.endsWith('.json')) userConfigFile += '.json';
    const {config: userConfig, error} =
        ts.readConfigFile(userConfigFile, host.readFile);
    if (error) {
      return [null, [error], {target}];
    }
    if (userConfig.bazelOptions) {
      bazelOpts.disableStrictDeps = bazelOpts.disableStrictDeps ||
          userConfig.bazelOptions.disableStrictDeps;
      bazelOpts.suppressTsconfigOverrideWarnings =
          bazelOpts.suppressTsconfigOverrideWarnings ||
          userConfig.bazelOptions.suppressTsconfigOverrideWarnings;
      bazelOpts.tsickle = bazelOpts.tsickle || userConfig.bazelOptions.tsickle;
      bazelOpts.googmodule =
          bazelOpts.googmodule || userConfig.bazelOptions.googmodule;
      bazelOpts.devmodeTargetOverride = bazelOpts.devmodeTargetOverride ||
          userConfig.bazelOptions.devmodeTargetOverride;
    }
    if (!bazelOpts.suppressTsconfigOverrideWarnings) {
      warnOnOverriddenOptions(userConfig);
    }
  }

  const {options, errors, fileNames} =
      ts.parseJsonConfigFileContent(config, host, path.dirname(tsconfigFile));
  if (errors && errors.length) {
    return [null, errors, {target}];
  }

  // Override the devmode target if devmodeTargetOverride is set
  if (bazelOpts.es5Mode && bazelOpts.devmodeTargetOverride) {
    switch (bazelOpts.devmodeTargetOverride.toLowerCase()) {
      case 'es3':
        options.target = ts.ScriptTarget.ES3;
        break;
      case 'es5':
        options.target = ts.ScriptTarget.ES5;
        break;
      case 'es2015':
        options.target = ts.ScriptTarget.ES2015;
        break;
      case 'es2016':
        options.target = ts.ScriptTarget.ES2016;
        break;
      case 'es2017':
        options.target = ts.ScriptTarget.ES2017;
        break;
      case 'es2018':
        options.target = ts.ScriptTarget.ES2018;
        break;
      case 'esnext':
        options.target = ts.ScriptTarget.ESNext;
        break;
      default:
        console.error(
            'WARNING: your tsconfig.json file specifies an invalid bazelOptions.devmodeTargetOverride value of: \'${bazelOpts.devmodeTargetOverride\'');
    }
  }

  // Sort rootDirs with longest include directories first.
  // When canonicalizing paths, we always want to strip
  // `workspace/bazel-bin/file` to just `file`, not to `bazel-bin/file`.
  if (options.rootDirs) options.rootDirs.sort((a, b) => b.length - a.length);

  // If the user requested goog.module, we need to produce that output even if
  // the generated tsconfig indicates otherwise.
  if (bazelOpts.googmodule) options.module = ts.ModuleKind.CommonJS;

  // TypeScript's parseJsonConfigFileContent returns paths that are joined, eg.
  // /path/to/project/bazel-out/arch/bin/path/to/package/../../../../../../path
  // We normalize them to remove the intermediate parent directories.
  // This improves error messages and also matches logic in tsc_wrapped where we
  // expect normalized paths.
  const files = fileNames.map(f => path.posix.normalize(f));

  // The bazelOpts paths in the tsconfig are relative to
  // options.rootDir (the workspace root) and aren't transformed by
  // parseJsonConfigFileContent (because TypeScript doesn't know
  // about them). Transform them to also be absolute here.
  bazelOpts.compilationTargetSrc = bazelOpts.compilationTargetSrc.map(
      f => resolveNormalizedPath(options.rootDir!, f));
  bazelOpts.allowedStrictDeps = bazelOpts.allowedStrictDeps.map(
      f => resolveNormalizedPath(options.rootDir!, f));
  bazelOpts.typeBlackListPaths = bazelOpts.typeBlackListPaths.map(
      f => resolveNormalizedPath(options.rootDir!, f));
  if (bazelOpts.nodeModulesPrefix) {
    bazelOpts.nodeModulesPrefix =
        resolveNormalizedPath(options.rootDir!, bazelOpts.nodeModulesPrefix);
  }

  let disabledTsetseRules: string[] = [];
  for (const pluginConfig of options['plugins'] as PluginImportWithConfig[] ||
       []) {
    if (pluginConfig.name && pluginConfig.name === '@bazel/tsetse') {
      const disabledRules = pluginConfig['disabledRules'];
      if (disabledRules && !Array.isArray(disabledRules)) {
        throw new Error('Disabled tsetse rules must be an array of rule names');
      }
      disabledTsetseRules = disabledRules as string[];
      break;
    }
  }

  return [
    {options, bazelOpts, files, config, disabledTsetseRules}, null, {target}
  ];
}
