/**
 * ESLint 9 plugin to automatically mark NSFW routes with the nsfw flag
 */
import { eslintCompatPlugin } from '@oxlint/plugins';

const nsfwRoutes = [
    '141jav',
    '141ppv',
    '18comic',
    '2048',
    '7mmtv',
    '8kcos',
    '91porn',
    '95mm',
    'abskoop',
    'asiantolick',
    'asmr-200',
    'booru',
    'chikubi',
    'chub',
    'civitai',
    'cool18',
    'coomer',
    'copymanga',
    'cosplaytele',
    'dlsite',
    'e-hentai',
    'ehentai',
    'everia',
    'fanbox',
    'fansly',
    'fantia',
    'freexcomic',
    'furaffinity',
    'gelbooru',
    'hanime1',
    'iwara',
    'javbus',
    'javdb',
    'javlibrary',
    'javtiful',
    'javtrailers',
    'jpxgmn',
    'kemono',
    'kisskiss',
    'komiic',
    'konachan',
    'koyso',
    'laimanhua',
    'literotica',
    'mangadex',
    'manhuagui',
    'manyvids',
    'missav',
    'netflav',
    'nhentai',
    'olevod',
    'oreno3d',
    'patreon',
    'pixiv',
    'pornhub',
    'rawkuma',
    'sehuatang',
    'shuiguopai',
    'sis001',
    'skeb',
    'skebetter',
    'spankbang',
    't66y',
    'uraaka-joshi',
    'wnacg',
    'xbookcn',
    'xmanhua',
    'xsijishe',
    'yande',
    'zaimanhua',
    'zodgame',
    '4kup',
    'misskon',
    '4khd',
];

// 检查是否是 NSFW 路由文件
function isNsfwRoute(filePath) {
    const normalizedPath = filePath.replaceAll('\\', '/');
    return nsfwRoutes.some((nsfwKey) => {
        const routePattern = `/lib/routes/${nsfwKey}/`;
        return normalizedPath.includes(routePattern);
    });
}

export default eslintCompatPlugin({
    meta: {
        name: '@rsshub/nsfw-flag',
        version: '1.0.0',
    },
    configs: {
        recommended: {
            plugins: {
                '@rsshub/nsfw-flag': 'self',
            },
            rules: {
                '@rsshub/nsfw-flag/add-nsfw-flag': 'error',
            },
        },
    },
    rules: {
        'add-nsfw-flag': {
            meta: {
                type: 'problem',
                docs: {
                    description: 'Automatically add nsfw flag to NSFW routes',
                    category: 'Best Practices',
                    recommended: true,
                },
                fixable: 'code',
                schema: [],
                messages: {
                    missingNsfwFlag: 'NSFW route is missing the nsfw flag in features',
                },
            },
            createOnce(context) {
                return {
                    before() {
                        // 如果不是 NSFW 路由，跳过检查
                        if (!isNsfwRoute(context.filename)) {
                            return false;
                        }
                    },
                    ExportNamedDeclaration(node) {
                        // 查找 export const route: Route = {...}
                        if (
                            node.declaration &&
                            node.declaration.type === 'VariableDeclaration' &&
                            node.declaration.declarations &&
                            node.declaration.declarations[0] &&
                            node.declaration.declarations[0].id &&
                            node.declaration.declarations[0].id.name === 'route'
                        ) {
                            const routeDeclaration = node.declaration.declarations[0];
                            const routeObject = routeDeclaration.init;

                            if (routeObject && routeObject.type === 'ObjectExpression') {
                                let featuresProperty = null;
                                let nsfwProperty = null;

                                // 查找 features 属性
                                for (const prop of routeObject.properties) {
                                    if (prop.type === 'Property' && prop.key && prop.key.name === 'features') {
                                        featuresProperty = prop;

                                        // 在 features 中查找 nsfw 属性
                                        if (prop.value && prop.value.type === 'ObjectExpression') {
                                            for (const featureProp of prop.value.properties) {
                                                if (featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw') {
                                                    nsfwProperty = featureProp;
                                                    break;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                }

                                // 检查是否需要添加或修复 nsfw 标志
                                if (!featuresProperty) {
                                    // 没有 features 属性，需要添加整个 features 对象
                                    context.report({
                                        node: routeObject,
                                        messageId: 'missingNsfwFlag',
                                        fix(fixer) {
                                            // 在对象的最后添加 features 属性
                                            const lastProperty = routeObject.properties.at(-1);

                                            return lastProperty
                                                ? fixer.insertTextAfter(lastProperty, ',\n    features: {\n        nsfw: true,\n    }')
                                                : // 空对象的情况
                                                  fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n    features: {\n        nsfw: true,\n    }\n');
                                        },
                                    });
                                } else if (!nsfwProperty) {
                                    // 有 features 属性但没有 nsfw 属性
                                    context.report({
                                        node: featuresProperty.value,
                                        messageId: 'missingNsfwFlag',
                                        fix(fixer) {
                                            const featuresObject = featuresProperty.value;
                                            if (featuresObject.properties.length > 0) {
                                                const lastFeatureProp = featuresObject.properties.at(-1);
                                                return fixer.insertTextAfter(lastFeatureProp, ',\n        nsfw: true');
                                            } else {
                                                // features 是空对象
                                                return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n        nsfw: true,\n    ');
                                            }
                                        },
                                    });
                                } else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) {
                                    // nsfw 属性存在但不是 true
                                    context.report({
                                        node: nsfwProperty.value,
                                        messageId: 'missingNsfwFlag',
                                        fix(fixer) {
                                            return fixer.replaceText(nsfwProperty.value, 'true');
                                        },
                                    });
                                }
                            }
                        }
                    },
                };
            },
        },
    },
});
