package com.ruoyi.cms.util.sensitiveWord;

import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 前缀树（Trie树）节点
 */


/**
 * 前缀树（Trie树）工具类
 */
@Component
public class SensitiveWordTrie {
    // 根节点（无实际字符）
    private final TrieNode root = new TrieNode();

    /**
     * 向前缀树中添加敏感词
     */
    public void addWord(String word) {
        if (word == null || word.isEmpty()) {
            return;
        }
        TrieNode current = root;
        for (char c : word.toCharArray()) {
            // 若子节点中不存在该字符，则创建新节点
            current.getChildren().putIfAbsent(c, new TrieNode());
            // 移动到子节点
            current = current.getChildren().get(c);
        }
        // 标记当前节点为敏感词结尾
        current.setEnd(true);
    }

    /**
     * 检测文本中所有敏感词（去重）
     * @param text 待检测文本
     * @return 敏感词列表
     */
    public List<String> findAllSensitiveWords(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        Set<String> sensitiveWords = new HashSet<>();
        TrieNode current = root;
        StringBuilder currentWord = new StringBuilder(); // 记录当前匹配的字符

        for (int i = 0; i < text.length(); i++) {
            char c = text.charAt(i);

            // 若当前字符不在子节点中，重置匹配状态
            if (!current.getChildren().containsKey(c)) {
                current = root; // 回到根节点
                currentWord.setLength(0); // 清空当前匹配的字符
                continue;
            }

            // 匹配到字符，移动到子节点
            current = current.getChildren().get(c);
            currentWord.append(c);

            // 若当前节点是敏感词结尾，记录该敏感词
            if (current.isEnd()) {
                sensitiveWords.add(currentWord.toString());
            }
        }

        return new ArrayList<>(sensitiveWords);
    }

    /**
     * 批量添加敏感词到前缀树
     * @param words 敏感词列表
     */
    public void batchAddWords(List<String> words) {
        if (words == null || words.isEmpty()) {
            return;
        }
        // 批量处理比循环单次添加更高效，减少重复判断
        for (String word : words) {
            addWord(word);
        }
    }

    /**
     * 清空前缀树所有节点
     */
    public void clear() {
        // 清空根节点的子节点映射，达到清空整个前缀树的效果
        root.getChildren().clear();
    }

}