from abc import ABC, abstractmethod
from collections import Counter
from pathlib import Path
from typing import List, Set, Dict
import yaml

class BaseTokenizer(ABC):
    """分词器抽象基类"""
    @abstractmethod
    def tokenize(self, text: str, stop_words: Set[str]) -> List[str]:
        pass

class SimpleTokenizer(BaseTokenizer):
    """按空格分词"""
    def tokenize(self, text: str, stop_words: Set[str]) -> List[str]:
        return [word for word in text.split() if word not in stop_words]

class JiebaTokenizer(BaseTokenizer):
    """结巴分词（需安装jieba）"""
    def tokenize(self, text: str, stop_words: Set[str]) -> List[str]:
        import jieba
        return [word for word in jieba.lcut(text) if word not in stop_words]

class WordCounter:
    """词频统计核心类"""
    def __init__(self, config_path: str = "config/settings.yaml"):
        with open(config_path, 'r') as f:
            self.config = yaml.safe_load(f)
        self.stop_words = self._load_stop_words()
        self.tokenizer = self._init_tokenizer()

    def _load_stop_words(self) -> Set[str]:
        with open(self.config['stop_words_file'], 'r') as f:
            return {line.strip() for line in f}

    def _init_tokenizer(self) -> BaseTokenizer:
        tokenizers = {
            "simple": SimpleTokenizer(),
            "jieba": JiebaTokenizer()
        }
        return tokenizers[self.config['tokenizer']]

    def process_files(self) -> Dict[str, int]:
        """处理所有文件并返回词频统计"""
        counter = Counter()
        data_dir = Path(self.config['data_dir'])
        for file_path in data_dir.glob("*.txt"):
            with open(file_path, 'r', encoding='utf-8') as f:
                text = f.read()
                words = self.tokenizer.tokenize(text, self.stop_words)
                counter.update(words)
        return dict(counter.most_common(self.config['top_n']))