import os
import re
import xml.etree.ElementTree as ET
from collections import OrderedDict
from typing import List, Dict

# BaseJobのインポートパスは環境に合わせて調整してください
from pilot.job.impl.base_job import BaseJob

class SplitDivisionBaseJob(BaseJob):
    """
    COBOLソースファイルを読み込み、Divisionごとに分割して保持するジョブ
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 解析結果を格納するメンバ変数
        self.split_results: Dict[str, List[str]] = {}

    def run(self):
        """
        ジョブの実行メイン処理
        """
        try:
            # 1. ファイルの読み込み
            encoding = 'utf-8'
            with open(self.file_path, 'r', encoding=encoding, errors='ignore') as f:
                lines = f.readlines()

            # 2. メインロジックの実行
            merge_processed_lines = self._merge_continued_lines(lines)
            divisions = self._locate_divisions(merge_processed_lines)
            self.split_results = self._split_by_division(merge_processed_lines, divisions)

        except Exception as e:
            # エラーハンドリング
            self.logger.error(f"{__name__}異常終了. {e}")
            return
        
        # 3. 親クラスのrunを実行（完了ステータスへの更新など）
        super().run()

    def _locate_divisions(self, lines: List[str]) -> OrderedDict:
        """
        Divisionの開始位置を特定する
        """
        DIVISION_RE = re.compile(
            r"^\s*(IDENTIFICATION|ENVIRONMENT|DATA|PROCEDURE)\s+DIVISION\b",
            re.IGNORECASE,
        )

        divisions = OrderedDict()
        for idx, line in enumerate(lines):
            m = DIVISION_RE.match(line)
            if m:
                div_name = m.group(1).upper()
                divisions[div_name] = idx
        return divisions

    def _split_by_division(self, lines: List[str], divisions: OrderedDict) -> dict:
        """
        Divisionごとにリストを分割する
        """
        result = {}
        div_names = list(divisions.keys())
        for i, name in enumerate(div_names):
            start = divisions[name]
            end = divisions[div_names[i + 1]] if i + 1 < len(div_names) else len(lines)
            result[name] = lines[start:end]
        return result

    def _merge_continued_lines(self, lines: List[str]) -> List[str]:
        """
        行継続の結合処理
        """
        cobol_keywords = self._load_cobol_keywords()
        merged_lines = []
        current_line = ""
        
        for line in lines:
            stripped_line = line.strip()
            # 空行の特別処理
            if stripped_line == '':
                stripped_line = '//'
                # 元のロジックを維持: line変数自体も変更して結合に使用
                line = line.strip() + '\n'
            
            words = stripped_line.split()
            
            # キーワード判定ロジック
            is_keyword = words and words[0].upper() in cobol_keywords
            is_end_marker = words and words[0].upper().startswith('END-')

            if is_keyword:
                if current_line:
                    merged_lines.append(current_line)
                current_line = line
            elif is_end_marker:
                current_line = current_line + '\n' + line
            else:
                current_line += '' + line  # 単純結合

        if current_line:
            merged_lines.append(current_line)

        return merged_lines

    def _load_cobol_keywords(self) -> List[str]:
        """
        XMLファイルからキーワードをロードする
        """
        # 注意: BaseJob実行時のカレントディレクトリに依存します
        cwd = os.getcwd()
        # パス構成はプロジェクト構成に合わせて適宜変更してください
        xml_file = os.path.join(cwd, 'input', 'xml', 'cobol_keywords.xml')

        if not os.path.exists(xml_file):
            # ファイルが見つからない場合のフォールバックやエラーログなど
            print(f"Warning: Keywords file not found at {xml_file}")
            return []

        tree = ET.parse(xml_file)
        root = tree.getroot()
        keywords = [keyword.text.upper() for keyword in root.findall('keyword')]
        return keywords
    