
const eslint = require("@eslint/js");
const tseslint = require("typescript-eslint");
const jsdoc = require("eslint-plugin-jsdoc");
const diff  = require("eslint-plugin-diff");

// https://github.com/paleite/eslint-plugin-diff/issues/47#issuecomment-2480733106
const diffConfig = {
    plugins: {
        diff,
    },
    processor: diff.processors.diff,
}

module.exports = tseslint.config(
    {
        // these are autogenerated and thus should not be linted at all.
        ignores: [
            "res/controllers/lodash.mixxx.js",
            "res/controllers/Novation-Launchpad MK2-scripts.js",
            "res/controllers/Novation-Launchpad Mini MK3-scripts.js",
            "res/controllers/Novation-Launchpad-scripts.js",
        ],
    },
    {
        languageOptions: {
            ecmaVersion: 7,
            sourceType: "script",
        },
    },
    {
        plugins: {
            jsdoc,
        }
    },
    eslint.configs.recommended,
    tseslint.configs.recommended,
    jsdoc.configs['flat/recommended'],
    diffConfig,
    {
        files: ["res/controllers/**/*"],
        languageOptions: {
            globals: {
                // QJSEngine::ConsoleExtension, https://doc.qt.io/qt-6/qtquick-debugging.html#console-api
                "console": "readonly",
                // lodash, deprecated
                "_": "readonly",
                // Mixxx custom
                "ColorMapper": "readonly",
                "components": "readonly",
                "engine": "readonly",
                "midi": "readonly",
                // common-controller-scripts globals
                "print": "readonly",
                "printObject": "readonly",
                "stringifyObject": "readonly",
                "arrayContains": "readonly",
                "secondstominutes": "readonly",
                "msecondstominutes": "readonly",
                "colorCodeToObject": "readonly",
                "colorCodeFromObject": "readonly",
                "script": "readonly",
                "bpm": "readonly",
                "ButtonState": "readonly",
                "LedState": "readonly",
                "Controller": "readonly",
                "Button": "readonly",
                "Control": "readonly",
                "Deck": "readonly"
            }
        }
    },
    {
        // vanilla rule config from previous `.eslintrc`
        rules: {
            "array-bracket-spacing": "warn",
            "block-spacing": "warn",

            "brace-style": ["warn", "1tbs", {
                allowSingleLine: true,
            }],

            curly: "warn",
            camelcase: "warn",
            "comma-spacing": "warn",

            "computed-property-spacing": ["warn", "never", {
                enforceForClassMembers: true,
            }],

            "dot-location": ["warn", "property"],
            "dot-notation": "warn",
            eqeqeq: ["error", "always"],
            "func-call-spacing": "warn",

            "func-style": ["error", "expression", {
                allowArrowFunctions: true,
            }],

            indent: ["warn", 4],
            "key-spacing": "warn",
            "keyword-spacing": "warn",
            "linebreak-style": ["warn", "unix"],
            "newline-per-chained-call": "warn",
            "no-constructor-return": "warn",
            "no-extra-bind": "warn",
            "no-sequences": "warn",
            "no-useless-call": "warn",
            "no-useless-return": "warn",
            "no-trailing-spaces": "warn",

            "no-unneeded-ternary": ["warn", {
                defaultAssignment: false,
            }],

            "no-var": "warn",

            "object-curly-newline": ["warn", {
                consistent: true,
                multiline: true,
            }],

            "object-curly-spacing": "warn",
            "prefer-const": "warn",
            "prefer-regex-literals": "warn",
            "prefer-template": "warn",
            quotes: ["warn", "double"],
            "require-atomic-updates": "error",
            semi: "warn",
            "semi-spacing": "warn",
            "space-before-blocks": ["warn", "always"],
            "space-before-function-paren": ["warn", "never"],
            "space-in-parens": "warn",
            yoda: "warn",
        },
    },
    {
        // special rules required for the typescript plugin
        rules: {
            // Note: you must disable the base rule as it can report incorrect errors
            "no-unused-vars": "off",
            "@typescript-eslint/no-unused-vars": ["error", {
                argsIgnorePattern: "^_",
            }],
            // no need for jsdoc type annotation, the typescript syntax already requires it.
            "jsdoc/require-param-type": "off",
            "jsdoc/require-returns-type": "off",
            // this is commonly needed in ComponentsJS
            "@typescript-eslint/no-this-alias": "off",
            "@typescript-eslint/no-explicit-any": "off",
        }
    },
    {
        // JSDoc specific stuff
        rules: {
            // the style here is too mixed currently, disable for now
            "jsdoc/tag-lines": "off"
        }
    },
);
