import argparse
import os
import re
from pathlib import Path


# 除外パターンの定義 (パス全体に対して判定)
exclude_patterns = [
        r"/__init__\.py$",
        r"/.*_docstring\.",
        r"/.*_\d{8}\.",
        r"/tklib/",
        r"/cms/",
        r"/jsap_crystal/",
        r"/stastical_physics/",
    ]

def compare_directories(source_dir, target_dir, extension="*.py"):
    source_path = Path(source_dir)
    target_path = Path(target_dir)

    def is_excluded(rel_path_str):
        """
        相対パス（/区切り）が除外パターンにマッチするか確認
        先頭に / を付与してディレクトリ境界を明確にして判定
        """
        # マッチング用に先頭に / をつける
        test_path = "/" + rel_path_str
        return any(re.search(pattern, test_path) for pattern in exclude_patterns)

    # ファイル一覧を取得 (Path.as_posix() でセパレータを '/' に統一)
    def get_filtered_files(base_path):
        file_set = set()
        for p in base_path.rglob(extension):
            # ベースディレクトリからの相対パスを取得し '/' 区切りに変換
            rel_path = p.relative_to(base_path).as_posix()
            if not is_excluded(rel_path):
                file_set.add(rel_path)
        return file_set

    source_files = get_filtered_files(source_path)
    target_files = get_filtered_files(target_path)

    print(f"{'='*60}")
    print(f" 比較レポート (Separator: '/')")
    print(f"{'='*60}")
    print(f"・[A] Source: {source_path.absolute()}")
    print(f"・[B] Target: {target_path.absolute()}")
    print(f"{'-'*60}\n")

    # AにあってBにないもの
    only_in_source = sorted(source_files - target_files)
    print(f"【 状態: Source [A] にのみ存在 / Target [B] から欠落 】")
    if only_in_source:
        for f in only_in_source:
            print(f"  [MISSING in B] -> {f}")
    else:
        print("  該当なし")

    print("\n" + "-"*60 + "\n")

    # BにあってAにないもの
    only_in_target = sorted(target_files - source_files)
    print(f"【 状態: Target [B] にのみ存在 / Source [A] から欠落 】")
    if only_in_target:
        for f in only_in_target:
            print(f"  [MISSING in A] -> {f}")
    else:
        print("  該当なし")

def main():
    parser = argparse.ArgumentParser(description="特定のディレクトリやファイルパターンを除外して2つのツリーを比較します。")
    
    parser.add_argument("source", 
                        nargs="?",
                        default=r"D:\git\tkProg\tkprog_COE",
                        help="比較元ディレクトリ(A)")
    parser.add_argument("target", 
                        nargs="?",
                        default=r"D:\git\sphinx\tkProg\source",
                        help="比較先ディレクトリ(B)")
    parser.add_argument("-e", "--ext", 
                        default="*.py", 
                        help="検索パターン (デフォルト: *.py)")

    args = parser.parse_args()

    if not os.path.isdir(args.source) or not os.path.isdir(args.target):
        print("エラー: 指定されたパスが存在しないか、ディレクトリではありません。")
        return

    compare_directories(args.source, args.target, args.ext)

if __name__ == "__main__":
    main()