extends:
  - standard
  - standard-jsx
  - standard-react
  - plugin:@typescript-eslint/recommended
  - prettier
  - eslint:recommended

globals:
  JSX: 'readonly'

parserOptions:
  # Override eslint-config-standard, which incorrectly sets this to "module",
  # though that setting is only for ES6 modules, not CommonJS modules.
  sourceType: 'script'

settings:
  react:
    version: '16.8'
  jsdoc:
    mode: jsdoc

plugins:
  - chai-friendly
  - jsdoc
  - mocha
  - no-extension-in-require
  - sort-class-members
  - import
  - react-hooks
  - promise

overrides:
  # For simplicity's sake, when possible prefer to add rules to the top-level
  # list of rules, even if they only apply to certain files. That way the
  # rules listed here are only ones which conflict.

  - files:
      - '**/*.js'
      - '!frontend/**/*.js'
    env:
      node: true
      es6: true
    rules:
      no-console: 'off'
      '@typescript-eslint/explicit-module-boundary-types': 'off'

  - files:
      - '**/*.@(ts|tsx)'
    parserOptions:
      sourceType: 'module'
    parser: '@typescript-eslint/parser'
    rules:
      # Argh.
      '@typescript-eslint/explicit-function-return-type':
        ['error', { 'allowExpressions': true }]
      '@typescript-eslint/no-empty-function': 'error'
      '@typescript-eslint/no-var-requires': 'error'
      '@typescript-eslint/no-object-literal-type-assertion': 'off'
      '@typescript-eslint/no-explicit-any': 'error'
      '@typescript-eslint/ban-ts-ignore': 'off'
      '@typescript-eslint/explicit-module-boundary-types': 'off'

  - files:
      - core/**/*.ts
    parserOptions:
      sourceType: 'module'
    parser: '@typescript-eslint/parser'
  - files:
      - gatsby-browser.js
      - 'frontend/**/*.@(js|ts|tsx)'
    parserOptions:
      sourceType: 'module'
    env:
      browser: true
    rules:
      import/extensions:
        ['error', 'never', { 'json': 'always', 'yml': 'always' }]

  - files:
      - 'core/base-service/**/*.js'
      - 'services/**/*.js'
    rules:
      sort-class-members/sort-class-members:
        [
          'error',
          {
            order:
              [
                'name',
                'category',
                'isDeprecated',
                'route',
                'auth',
                'examples',
                '_cacheLength',
                'defaultBadgeData',
                'render',
                'constructor',
                'fetch',
                'transform',
                'handle',
              ],
          },
        ]

  - files:
      - '**/*.spec.@(js|ts|tsx)'
      - '**/*.integration.js'
      - '**/test-helpers.js'
      - 'core/service-test-runner/**/*.js'
    env:
      mocha: true
    rules:
      mocha/no-exclusive-tests: 'error'
      mocha/no-mocha-arrows: 'error'
      mocha/prefer-arrow-callback: 'error'

rules:
  # Disable some rules from eslint:recommended.
  no-empty: ['error', { 'allowEmptyCatch': true }]

  # Allow unused parameters. In callbacks, removing them seems to obscure
  # what the functions are doing.
  '@typescript-eslint/no-unused-vars': ['error', { 'args': 'none' }]
  no-unused-vars: 'off'

  '@typescript-eslint/no-var-requires': 'off'

  '@typescript-eslint/no-use-before-define': 'error'
  no-use-before-define: 'off'

  # These should be disabled by eslint-config-prettier, but are not.
  no-extra-semi: 'off'

  # Shields additions.
  no-var: 'error'
  prefer-const: 'error'
  strict: 'error'
  arrow-body-style: ['error', 'as-needed']
  no-extension-in-require/main: 'error'
  object-shorthand: ['error', 'properties']
  prefer-template: 'error'
  promise/prefer-await-to-then: 'error'
  func-style: ['error', 'declaration', { 'allowArrowFunctions': true }]
  new-cap: ['error', { 'capIsNew': true }]
  import/order: ['error', { 'newlines-between': 'never' }]

  # Account for destructuring responses from upstream services,
  # many of which do not follow camelcase
  # Based on original rule configuration from eslint-config-standard
  camelcase:
    [
      'error',
      {
        ignoreDestructuring: true,
        properties: 'never',
        ignoreGlobals: true,
        allow: ['^UNSAFE_'],
      },
    ]

  # Chai friendly.
  no-unused-expressions: 'off'
  chai-friendly/no-unused-expressions: 'error'

  # jsdoc plugin:
  # don't require every class/function to have a docblock
  jsdoc/require-jsdoc: 'off'

  # allow Joi as an undefined type
  jsdoc/no-undefined-types: ['error', { definedTypes: ['Joi'] }]

  # all the other recommended rules as errors (not warnings)
  jsdoc/check-alignment: 'error'
  jsdoc/check-param-names: 'error'
  jsdoc/check-tag-names: 'error'
  jsdoc/check-types: 'error'
  jsdoc/implements-on-classes: 'error'
  jsdoc/newline-after-description: 'error'
  jsdoc/require-param: 'error'
  jsdoc/require-param-description: 'error'
  jsdoc/require-param-name: 'error'
  jsdoc/require-param-type: 'error'
  jsdoc/require-returns: 'error'
  jsdoc/require-returns-check: 'error'
  jsdoc/require-returns-description: 'error'
  jsdoc/require-returns-type: 'error'
  jsdoc/valid-types: 'error'

  # Disable some from TypeScript.
  '@typescript-eslint/camelcase': off
  '@typescript-eslint/explicit-function-return-type': 'off'
  '@typescript-eslint/no-empty-function': 'off'

  react/jsx-sort-props: 'error'
  react-hooks/rules-of-hooks: 'error'
  react-hooks/exhaustive-deps: 'error'
  jsx-quotes: ['error', 'prefer-double']
