/*
 * Copyright (c) 2026 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const fs = require('fs');
const path = require('path');

function getComponents() {
  const componentsPath = path.join(
    __dirname,
    'packages/react-native-harmony/Libraries/Components',
  );
  if (fs.existsSync(componentsPath)) {
    return fs
      .readdirSync(componentsPath)
      .filter((dir) =>
        fs.statSync(path.join(componentsPath, dir)).isDirectory(),
      );
  }
  return [];
}

const components = getComponents();

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      [
        'feat',
        'fix',
        'docs',
        'style',
        'refactor',
        'perf',
        'test',
        'chore',
        'deprecated',
        'removed',
        'security',
        'revert',
      ],
    ],
    'type-case': [2, 'always', 'lower-case'],
    'type-empty': [2, 'never'],
    'scope-enum': [
      2,
      'always',
      [
        ...components,
        'View',
        'Text',
        'Image',
        'TextInput',
        'ScrollView',
        'FlatList',
        'ListView',
        'WebView',
        'Modal',
        'RefreshControl',
        'ActivityIndicator',
        'Flex',
        'Absolute',
        'SafeArea',
        'KeyboardAvoidingView',
        'Networking',
        'Storage',
        'AsyncStorage',
        'Clipboard',
        'Linking',
        'Alert',
        'Toast',
        'Permissions',
        'DeviceInfo',
        'Animated',
        'Reanimated',
        'LayoutAnimation',
        'GestureHandler',
        'Navigation',
        'ReactNavigation',
        'StackNavigator',
        'StyleSheet',
        'StyleSheetOptimizer',
        'Theme',
        'Bridge',
        'TurboModules',
        'Fabric',
        'LegacyComponents',
        'Hermes',
        'JSC',
        'JSI',
        'JSVM',
        'BuildSystem',
        'CMake',
        'HAP',
        'HAR',
        'Symbols',
        'DevTools',
        'Debugger',
        'Profiler',
        'Flipper',
        'Tests',
        'E2E',
        'UnitTests',
        'Docs',
        'Examples',
        'Config',
        'CLI',
        'Scripts',
        'Upgrade',
        'Performance',
      ],
    ],
    'scope-case': [2, 'always', 'pascal-case'],
    'scope-empty': [0],
    'subject-empty': [2, 'never'],
    'subject-case': [0],
    'subject-full-stop': [2, 'never', '.'],
    'header-max-length': [2, 'always', 100],
    'body-max-line-length': [2, 'always', 100],
    'footer-max-line-length': [2, 'always', 100],
    'signed-off-by': [2, 'always'],
    'references-empty': [0],
    'rnoh-dco-email-match': [2, 'always'],
    'rnoh-body-required': [2, 'always'],
    'rnoh-symbols-change-warning': [1, 'always'],
    'rnoh-native-change-warning': [1, 'always'],
    'rnoh-build-change-warning': [1, 'always'],
    'rnoh-component-change-warning': [1, 'always'],
    'rnoh-breaking-change-format': [2, 'always'],
    'rnoh-stability-ref-warning': [2, 'always'],
    'rnoh-subject-english': [2, 'always'],
    'rnoh-impact-required': [2, 'always'],
  },
  plugins: [
    {
      rules: {
        'rnoh-dco-email-match': ({ raw }) => {
          const signedOffByMatch = raw.match(/Signed-off-by:\s*(.+)/);
          if (!signedOffByMatch) {
            return [
              false,
              'commit 必须包含 Signed-off-by 签名行,格式: Signed-off-by: Name <your-email>\n使用 git commit --signoff 或手动添加\nDCO签署参考: docs/zh-cn/06-社区/社区规范/开发者共建指南.md - 第5节',
            ];
          }
          const email = signedOffByMatch[1].match(/<([^>]+)>/);
          if (!email) {
            return [
              false,
              'Signed-off-by 需包含邮箱地址,格式: Signed-off-by: Name <your-email>\nDCO签署参考: docs/zh-cn/06-社区/社区规范/开发者共建指南.md - 第5节',
            ];
          }
          return [true];
        },
        'rnoh-body-required': ({ type, body }) => {
          const requiredTypes = [
            'feat',
            'fix',
            'refactor',
            'perf',
            'deprecated',
            'removed',
            'security',
          ];
          if (requiredTypes.includes(type) && !body) {
            return [
              false,
              `${type} 类型commit必须提供body说明详细内容\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md`,
            ];
          }
          return [true];
        },
        'rnoh-symbols-change-warning': ({ scope, body }) => {
          if (
            scope === 'Symbols' &&
            !body?.includes('符号') &&
            !body?.includes('.sym') &&
            !body?.includes('llvm-objcopy')
          ) {
            return [
              0,
              'Symbols变更建议说明符号处理情况(如:符号分离、剥离、路径等)\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第3节',
            ];
          }
          return [true];
        },
        'rnoh-native-change-warning': ({ scope, body }) => {
          const nativeScopes = [
            'Hermes',
            'JSI',
            'JSVM',
            'Bridge',
            'TurboModules',
            'Fabric',
          ];
          if (
            nativeScopes.includes(scope) &&
            !body?.includes('符号') &&
            !body?.includes('.so')
          ) {
            return [
              0,
              'Native层变更建议说明符号处理和.so文件影响\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第3节',
            ];
          }
          return [true];
        },
        'rnoh-build-change-warning': ({ scope, body }) => {
          const buildScopes = ['BuildSystem', 'CMake', 'HAP', 'HAR'];
          if (
            buildScopes.includes(scope) &&
            !body?.includes('Debug') &&
            !body?.includes('Release')
          ) {
            return [
              0,
              '构建系统变更建议说明对Debug/Release/Release2模式的影响\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第3节',
            ];
          }
          return [true];
        },
        'rnoh-component-change-warning': ({ scope, body }) => {
          const componentScopes = [
            'View',
            'Text',
            'Image',
            'ScrollView',
            'FlatList',
            'ListView',
            'WebView',
            'Modal',
          ];
          if (
            componentScopes.includes(scope) &&
            !body?.includes('兼容性') &&
            !body?.includes('API')
          ) {
            return [
              0,
              '组件变更建议说明兼容性和API变化\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第3节',
            ];
          }
          return [true];
        },
        'rnoh-breaking-change-format': ({ body, footer }) => {
          const content = (body || '') + '\n' + (footer || '');
          if (
            content.includes('BREAKING CHANGE') ||
            content.includes('BREAKING-CHANGE')
          ) {
            if (
              !content.includes('BREAKING CHANGE:') &&
              !content.includes('BREAKING-CHANGE:')
            ) {
              return [
                2,
                '破坏性变更必须以 "BREAKING CHANGE:" 开头,并详细说明变更内容、影响范围、适配方案。\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md',
              ];
            }
            if (
              !content.includes('影响范围') &&
              !content.includes('适配方案') &&
              !content.includes('适配指南')
            ) {
              return [
                1,
                '破坏性变更建议补充影响范围和适配方案/适配指南。\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md',
              ];
            }
          }
          return [true];
        },
        'rnoh-stability-ref-warning': ({ subject, body }) => {
          const stabilityKeywords = [
            'crash',
            'freeze',
            'frozen',
            'hang',
            'leak',
            'OOM',
            'oom',
            'ANR',
            'anr',
            'memory',
            '死机',
            '冻屏',
            '崩溃',
            '闪退',
            '内存泄漏',
            '内存异常',
          ];
          const content = (subject || '') + '\n' + (body || '');
          const matched = stabilityKeywords.find((kw) =>
            content.toLowerCase().includes(kw.toLowerCase()),
          );
          if (matched) {
            return [
              false,
              `commit 内容包含稳定性关键词 "${matched}",建议在 body 中引用历史稳定性修复文档作为参考。\n参考: docs/zh-cn/05-运维/稳定性历史修复/`,
            ];
          }
          return [true];
        },
        'rnoh-subject-english': ({ subject }) => {
          if (!subject) {
            return [true];
          }
          const chineseRegex = /[\u4e00-\u9fff\u3400-\u4dbf]/;
          if (chineseRegex.test(subject)) {
            return [
              false,
              'subject 必须使用英文,不允许中文。\n示例: feat(View): add pull-to-refresh support\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第1节',
            ];
          }
          return [true];
        },
        'rnoh-impact-required': ({ type, body }) => {
          const impactRequiredTypes = [
            'feat',
            'fix',
            'refactor',
            'perf',
            'security',
            'deprecated',
            'removed',
          ];
          if (!impactRequiredTypes.includes(type) || !body) {
            return [true];
          }
          const hasImpact =
            body.includes('影响范围') ||
            body.includes('影响') ||
            body.toLowerCase().includes('impact') ||
            body.toLowerCase().includes('affects') ||
            body.toLowerCase().includes('affected') ||
            body.toLowerCase().includes('scope of impact') ||
            /\bscope\b/i.test(body);
          if (!hasImpact) {
            return [
              false,
              `${type} 类型commit建议在body中说明影响范围(如:影响哪些模块/功能/API/版本)。\n示例: 影响范围: 所有使用ScrollView的页面\n参考: docs/zh-cn/06-社区/社区规范/社区commit和pr规范.md - 第2节`,
            ];
          }
          return [true];
        },
      },
    },
  ],
};