import js from "@eslint/js";
import prettier from "eslint-config-prettier";
import jsdoc from "eslint-plugin-jsdoc";

export default [
  js.configs.recommended,
  {
    files: ["**/*.js"],
    languageOptions: {
      ecmaVersion: 2022,
      globals: {
        ARGV: "readonly",
        Debugger: "readonly",
        GIRepositoryGType: "readonly",
        globalThis: "readonly",
        imports: "readonly",
        Intl: "readonly",
        log: "readonly",
        logError: "readonly",
        print: "readonly",
        printerr: "readonly",
        window: "readonly",
        TextEncoder: "readonly",
        TextDecoder: "readonly",
        console: "readonly",
        setTimeout: "readonly",
        setInterval: "readonly",
        clearTimeout: "readonly",
        clearInterval: "readonly",
      },
    },
    plugins: {
      jsdoc,
    },
    settings: {
      jsdoc: {
        mode: "typescript",
      },
    },
    rules: {
      "array-bracket-newline": ["error", "consistent"],
      "array-bracket-spacing": ["error", "never"],
      "array-callback-return": "error",
      "arrow-parens": ["error", "as-needed"],
      "arrow-spacing": "error",
      "block-scoped-var": "error",
      "block-spacing": "error",
      "brace-style": "error",
      "comma-dangle": [
        "error",
        {
          arrays: "always-multiline",
          objects: "always-multiline",
          functions: "never",
        },
      ],
      "comma-spacing": ["error", { before: false, after: true }],
      "comma-style": ["error", "last"],
      "computed-property-spacing": "error",
      curly: ["error", "multi-or-nest", "consistent"],
      "dot-location": ["error", "property"],
      "eol-last": "error",
      eqeqeq: "error",
      "func-call-spacing": "error",
      "func-name-matching": "error",
      "func-style": ["error", "declaration", { allowArrowFunctions: true }],
      indent: [
        "error",
        4,
        {
          ignoredNodes: [
            "CallExpression[callee.object.name=GObject][callee.property.name=registerClass] > ClassExpression:first-child",
          ],
        },
      ],
      "jsdoc/check-alignment": "error",
      "jsdoc/check-param-names": "error",
      "jsdoc/check-tag-names": "error",
      "jsdoc/check-types": "error",
      "jsdoc/implements-on-classes": "error",
      "jsdoc/tag-lines": ["error", "any", { startLines: 1 }],
      "jsdoc/require-jsdoc": "error",
      "jsdoc/require-param": "error",
      "jsdoc/require-param-description": "error",
      "jsdoc/require-param-name": "error",
      "jsdoc/require-param-type": "error",
      "key-spacing": ["error", { beforeColon: false, afterColon: true }],
      "keyword-spacing": ["error", { before: true, after: true }],
      "linebreak-style": ["error", "unix"],
      "lines-between-class-members": [
        "error",
        "always",
        { exceptAfterSingleLine: true },
      ],
      "max-nested-callbacks": "error",
      "max-statements-per-line": "error",
      "new-parens": "error",
      "no-array-constructor": "error",
      "no-await-in-loop": "error",
      "no-caller": "error",
      "no-constant-condition": ["error", { checkLoops: false }],
      "no-div-regex": "error",
      "no-empty": ["error", { allowEmptyCatch: true }],
      "no-extra-bind": "error",
      "no-extra-parens": [
        "error",
        "all",
        {
          conditionalAssign: false,
          nestedBinaryExpressions: false,
          returnAssign: false,
        },
      ],
      "no-implicit-coercion": ["error", { allow: ["!!"] }],
      "no-invalid-this": "error",
      "no-iterator": "error",
      "no-label-var": "error",
      "no-lonely-if": "error",
      "no-loop-func": "error",
      "no-nested-ternary": "error",
      "no-new-object": "error",
      "no-new-wrappers": "error",
      "no-octal-escape": "error",
      "no-proto": "error",
      "no-prototype-builtins": "off",
      "no-restricted-globals": ["error", "window"],
      "no-restricted-properties": [
        "error",
        {
          object: "Lang",
          property: "copyProperties",
          message: "Use Object.assign()",
        },
        {
          object: "Lang",
          property: "bind",
          message: "Use arrow notation or Function.prototype.bind()",
        },
        { object: "Lang", property: "Class", message: "Use ES6 classes" },
      ],
      "no-restricted-syntax": [
        "error",
        {
          selector:
            'MethodDefinition[key.name="_init"] > FunctionExpression[params.length=1] > BlockStatement[body.length=1] CallExpression[arguments.length=1][callee.object.type="Super"][callee.property.name="_init"] > Identifier:first-child',
          message: "_init() that only calls super._init() is unnecessary",
        },
        {
          selector:
            'MethodDefinition[key.name="_init"] > FunctionExpression[params.length=0] > BlockStatement[body.length=1] CallExpression[arguments.length=0][callee.object.type="Super"][callee.property.name="_init"]',
          message: "_init() that only calls super._init() is unnecessary",
        },
        {
          selector:
            'BinaryExpression[operator="instanceof"][right.name="Array"]',
          message: "Use Array.isArray()",
        },
      ],
      "no-return-assign": "error",
      "no-return-await": "error",
      "no-self-compare": "error",
      "no-shadow": "error",
      "no-shadow-restricted-names": "error",
      "no-spaced-func": "error",
      "no-tabs": "error",
      "no-template-curly-in-string": "error",
      "no-throw-literal": "error",
      "no-trailing-spaces": "error",
      "no-undef-init": "error",
      "no-unneeded-ternary": "error",
      "no-unused-expressions": "error",
      "no-unused-vars": [
        "error",
        {
          varsIgnorePattern: "(^unused|_$)",
          argsIgnorePattern: "^(unused|_)",
        },
      ],
      "no-useless-call": "error",
      "no-useless-computed-key": "error",
      "no-useless-concat": "error",
      "no-useless-constructor": "error",
      "no-useless-rename": "error",
      "no-useless-return": "error",
      "no-whitespace-before-property": "error",
      "no-with": "error",
      "nonblock-statement-body-position": ["error", "below"],
      "object-curly-newline": ["error", { consistent: true, multiline: true }],
      "object-curly-spacing": "error",
      "object-shorthand": "error",
      "operator-assignment": "error",
      "operator-linebreak": "error",
      "padded-blocks": ["error", "never"],
      "prefer-numeric-literals": "error",
      "prefer-promise-reject-errors": "error",
      "prefer-rest-params": "error",
      "prefer-spread": "error",
      "prefer-template": "error",
      quotes: ["error", "single", { avoidEscape: true }],
      "require-await": "error",
      "rest-spread-spacing": "error",
      semi: ["error", "always"],
      "semi-spacing": ["error", { before: false, after: true }],
      "semi-style": "error",
      "space-before-blocks": "error",
      "space-before-function-paren": [
        "error",
        {
          named: "never",
          anonymous: "always",
          asyncArrow: "always",
        },
      ],
      "space-in-parens": "error",
      "space-infix-ops": ["error", { int32Hint: false }],
      "space-unary-ops": "error",
      "spaced-comment": "error",
      "switch-colon-spacing": "error",
      "symbol-description": "error",
      "template-curly-spacing": "error",
      "template-tag-spacing": "error",
      "unicode-bom": "error",
      "wrap-iife": ["error", "inside"],
      "yield-star-spacing": "error",
      yoda: "error",
    },
  },
  prettier,
  {
    ignores: [
      "eslint.config.js",
      "dist/**/*",
      "node_modules/**",
      "scripts/**/*",
    ],
  },
];
