/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import type {Config} from '@jest/types';
import {replacePathSepForRegex} from 'jest-regex-util';
import {multipleValidOptions} from 'jest-validate';
import {DEFAULT_OPTIONS as PRETTY_FORMAT_DEFAULTS} from 'pretty-format';
import {NODE_MODULES} from './constants';

const NODE_MODULES_REGEXP = replacePathSepForRegex(NODE_MODULES);

export const initialOptions: Config.InitialOptions = {
  automock: false,
  bail: multipleValidOptions(false, 0),
  cache: true,
  cacheDirectory: '/tmp/user/jest',
  changedFilesWithAncestor: false,
  changedSince: 'master',
  ci: false,
  clearMocks: false,
  collectCoverage: true,
  collectCoverageFrom: ['src', '!public'],
  collectTests: false,
  coverageDirectory: 'coverage',
  coveragePathIgnorePatterns: [NODE_MODULES_REGEXP],
  coverageProvider: 'v8',
  coverageReporters: ['json', 'text', 'lcov', 'clover'],
  coverageThreshold: {
    global: {
      branches: 50,
      functions: 100,
      lines: 100,
      statements: 100,
    },
  },
  dependencyExtractor: '<rootDir>/dependencyExtractor.js',
  detectLeaks: false,
  detectOpenHandles: false,
  displayName: multipleValidOptions('test-config', {
    color: 'blue',
    name: 'test-config',
  } as const),
  errorOnDeprecated: false,
  expand: false,
  extensionsToTreatAsEsm: [],
  fakeTimers: {
    advanceTimers: multipleValidOptions(40, true),
    doNotFake: [
      'Date',
      'hrtime',
      'nextTick',
      'performance',
      'queueMicrotask',
      'requestAnimationFrame',
      'cancelAnimationFrame',
      'requestIdleCallback',
      'cancelIdleCallback',
      'setImmediate',
      'clearImmediate',
      'setInterval',
      'clearInterval',
      'setTimeout',
      'clearTimeout',
    ],
    enableGlobally: true,
    legacyFakeTimers: false,
    now: 1_483_228_800_000,
    timerLimit: 1000,
  },
  filter: '<rootDir>/filter.js',
  findRelatedTests: false,
  forceCoverageMatch: ['**/*.t.js'],
  forceExit: false,
  globalSetup: 'setup.js',
  globalTeardown: 'teardown.js',
  globals: {__DEV__: true},
  haste: {
    computeSha1: true,
    defaultPlatform: 'ios',
    enableSymlinks: false,
    forceNodeFilesystemAPI: true,
    hasteImplModulePath: '<rootDir>/haste_impl.js',
    hasteMapModulePath: '',
    platforms: ['ios', 'android'],
    retainAllFiles: false,
    throwOnModuleCollision: false,
  },
  id: 'string',
  injectGlobals: true,
  json: false,
  lastCommit: false,
  listTests: false,
  logHeapUsage: true,
  maxConcurrency: 5,
  maxWorkers: '50%',
  moduleDirectories: ['node_modules'],
  moduleFileExtensions: [
    'js',
    'mjs',
    'cjs',
    'json',
    'jsx',
    'ts',
    'mts',
    'cts',
    'tsx',
    'node',
  ],
  moduleNameMapper: {
    '^React$': '<rootDir>/node_modules/react',
  },
  modulePathIgnorePatterns: ['<rootDir>/build/'],
  modulePaths: ['/shared/vendor/modules'],
  noStackTrace: false,
  notify: false,
  notifyMode: 'failure-change',
  onlyChanged: false,
  onlyFailures: false,
  openHandlesTimeout: 1000,
  outputFile: '/tmp/jest-results.json',
  passWithNoTests: false,
  preset: 'react-native',
  prettierPath: '<rootDir>/node_modules/prettier',
  projects: ['project-a', 'project-b/'],
  randomize: false,
  replname: 'jest-hierarchical-repl',
  reporters: [
    'default',
    'custom-reporter-1',
    ['custom-reporter-2', {configValue: true}],
  ],
  resetMocks: false,
  resetModules: false,
  resolver: '<rootDir>/resolver.js',
  restoreMocks: false,
  rootDir: '/',
  roots: ['<rootDir>'],
  runTestsByPath: false,
  runner: multipleValidOptions('jest-runner', [
    'jest-runner',
    ['jest-runner', {option: true}],
  ]) as unknown as string,
  runtime: '<rootDir>',
  sandboxInjectedGlobals: [],
  setupFiles: ['<rootDir>/setup.js'],
  setupFilesAfterEnv: ['<rootDir>/testSetupFile.js'],
  showSeed: false,
  silent: true,
  skipFilter: false,
  skipNodeResolution: false,
  slowTestThreshold: 5,
  snapshotFormat: PRETTY_FORMAT_DEFAULTS,
  snapshotResolver: '<rootDir>/snapshotResolver.js',
  snapshotSerializers: ['my-serializer-module'],
  testEnvironment: 'jest-environment-node',
  testEnvironmentOptions: {
    url: 'http://localhost',
    userAgent: 'Agent/007',
  },
  testFailureExitCode: 1,
  testLocationInResults: false,
  testMatch: multipleValidOptions(
    '**/__tests__/**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
    [
      '**/__tests__/**/*.?([mc])[jt]s?(x)',
      '**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
    ],
  ),
  testNamePattern: 'test signature',
  testPathIgnorePatterns: [NODE_MODULES_REGEXP],
  testRegex: multipleValidOptions(
    '(/__tests__/.*|(\\.|/)(test|spec))\\.[mc]?[jt]sx?$',
    [
      '/__tests__/\\.test\\.[mc]?[jt]sx?$',
      '/__tests__/\\.spec\\.[mc]?[jt]sx?$',
    ],
  ),
  testResultsProcessor: 'processor-node-module',
  testRunner: 'circus',
  testSequencer: '@jest/test-sequencer',
  testTimeout: 5000,
  transform: {
    '\\.js$': '<rootDir>/preprocessor.js',
  },
  transformIgnorePatterns: [NODE_MODULES_REGEXP],
  unmockedModulePathPatterns: ['mock'],
  updateSnapshot: true,
  useStderr: false,
  verbose: false,
  waitForUnhandledRejections: false,
  watch: false,
  watchAll: false,
  watchPathIgnorePatterns: ['<rootDir>/e2e/'],
  watchPlugins: [
    'path/to/yourWatchPlugin',
    [
      'jest-watch-typeahead/filename',
      {
        key: 'k',
        prompt: 'do something with my custom prompt',
      },
    ],
  ],
  watchman: true,
  workerGracefulExitTimeout: 500,
  workerIdleMemoryLimit: multipleValidOptions(0.2, '50%'),
  workerThreads: true,
};

export const initialProjectOptions: Config.InitialProjectOptions = {
  automock: false,
  cache: true,
  cacheDirectory: '/tmp/user/jest',
  clearMocks: false,
  collectCoverage: false,
  collectCoverageFrom: ['src', '!public'],
  coverageDirectory: 'coverage',
  coveragePathIgnorePatterns: [NODE_MODULES_REGEXP],
  coverageProvider: 'v8',
  coverageReporters: ['json', 'text', 'lcov', 'clover'],
  dependencyExtractor: '<rootDir>/dependencyExtractor.js',
  detectLeaks: false,
  detectOpenHandles: false,
  displayName: multipleValidOptions('test-config', {
    color: 'blue',
    name: 'test-config',
  } as const),
  errorOnDeprecated: false,
  extensionsToTreatAsEsm: [],
  fakeTimers: {
    advanceTimers: multipleValidOptions(40, true),
    doNotFake: [
      'Date',
      'hrtime',
      'nextTick',
      'performance',
      'queueMicrotask',
      'requestAnimationFrame',
      'cancelAnimationFrame',
      'requestIdleCallback',
      'cancelIdleCallback',
      'setImmediate',
      'clearImmediate',
      'setInterval',
      'clearInterval',
      'setTimeout',
      'clearTimeout',
    ],
    enableGlobally: true,
    legacyFakeTimers: false,
    now: 1_483_228_800_000,
    timerLimit: 1000,
  },
  filter: '<rootDir>/filter.js',
  forceCoverageMatch: ['**/*.t.js'],
  globalSetup: 'setup.js',
  globalTeardown: 'teardown.js',
  globals: {__DEV__: true},
  haste: {
    computeSha1: true,
    defaultPlatform: 'ios',
    enableSymlinks: false,
    forceNodeFilesystemAPI: true,
    hasteImplModulePath: '<rootDir>/haste_impl.js',
    hasteMapModulePath: '',
    platforms: ['ios', 'android'],
    retainAllFiles: false,
    throwOnModuleCollision: false,
  },
  id: 'string',
  injectGlobals: true,
  moduleDirectories: ['node_modules'],
  moduleFileExtensions: [
    'js',
    'mjs',
    'cjs',
    'json',
    'jsx',
    'ts',
    'mts',
    'cts',
    'tsx',
    'node',
  ],
  moduleNameMapper: {
    '^React$': '<rootDir>/node_modules/react',
  },
  modulePathIgnorePatterns: ['<rootDir>/build/'],
  modulePaths: ['/shared/vendor/modules'],
  openHandlesTimeout: 1000,
  preset: 'react-native',
  prettierPath: '<rootDir>/node_modules/prettier',
  reporters: [
    'default',
    'custom-reporter-1',
    ['custom-reporter-2', {configValue: true}],
  ],
  resetMocks: false,
  resetModules: false,
  resolver: '<rootDir>/resolver.js',
  restoreMocks: false,
  rootDir: '/',
  roots: ['<rootDir>'],
  runner: multipleValidOptions('jest-runner', [
    'jest-runner',
    ['jest-runner', {option: true}],
  ]) as unknown as string,
  runtime: '<rootDir>',
  sandboxInjectedGlobals: [],
  setupFiles: ['<rootDir>/setup.js'],
  setupFilesAfterEnv: ['<rootDir>/testSetupFile.js'],
  silent: false,
  skipFilter: false,
  skipNodeResolution: false,
  slowTestThreshold: 5,
  snapshotFormat: PRETTY_FORMAT_DEFAULTS,
  snapshotResolver: '<rootDir>/snapshotResolver.js',
  snapshotSerializers: ['my-serializer-module'],
  testEnvironment: 'jest-environment-node',
  testEnvironmentOptions: {
    url: 'http://localhost',
    userAgent: 'Agent/007',
  },
  testLocationInResults: false,
  testMatch: [
    '**/__tests__/**/*.?([mc])[jt]s?(x)',
    '**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
  ],
  testPathIgnorePatterns: [NODE_MODULES_REGEXP],
  testRegex: multipleValidOptions(
    '(/__tests__/.*|(\\.|/)(test|spec))\\.[mc]?[jt]sx?$',
    [
      '/__tests__/\\.test\\.[mc]?[jt]sx?$',
      '/__tests__/\\.spec\\.[mc]?[jt]sx?$',
    ],
  ),
  testRunner: 'circus',
  testTimeout: 5000,
  transform: {
    '\\.js$': '<rootDir>/preprocessor.js',
  },
  transformIgnorePatterns: [NODE_MODULES_REGEXP],
  unmockedModulePathPatterns: ['mock'],
  verbose: false,
  waitForUnhandledRejections: false,
  watchPathIgnorePatterns: ['<rootDir>/e2e/'],
  workerIdleMemoryLimit: multipleValidOptions(0.2, '50%'),
};
