"""C-2 변경 관리 CAB 테스트"""
import sys, ast, os

os.environ.setdefault("GUARDIA_SECRET_KEY", "test-c2-secret-key-32bytes-padded!")
os.environ.setdefault("DATABASE_URL", "sqlite+aiosqlite:///./test_c2.db")

ok = True

print("=== 1. 구문 검사 ===")
files = ["routers/change.py", "models.py", "main.py"]
for f in files:
    try:
        with open(f, encoding="utf-8") as fh:
            src = fh.read()
        ast.parse(src)
        print(f"  OK  {f}")
    except SyntaxError as e:
        print(f"  ERR {f}: {e}")
        ok = False

print("\n=== 2. models.py CAB 모델 확인 ===")
with open("models.py", encoding="utf-8") as f:
    models_src = f.read()

model_checks = [
    ("class RFChange(Base):", "RFChange ORM 클래스 (RFC)"),
    ("class CABVote(Base):", "CABVote ORM 클래스"),
    ("class FreezeWindow(Base):", "FreezeWindow ORM 클래스"),
    ("class RFCStatus(str, Enum):", "RFCStatus Enum"),
    ("class ChangeType(str, Enum):", "ChangeType Enum"),
    ("class ChangeRisk(str, Enum):", "ChangeRisk Enum"),
    ("class CABVoteResult(str, Enum):", "CABVoteResult Enum"),
    ("RFChangeOut", "RFChangeOut Pydantic"),
    ("RFChangeCreate", "RFChangeCreate Pydantic"),
    ("CABVoteCreate", "CABVoteCreate Pydantic"),
    ("FreezeWindowOut", "FreezeWindowOut Pydantic"),
    ("FreezeWindowCreate", "FreezeWindowCreate Pydantic"),
    ("tb_rfc", "tb_rfc 테이블명"),
    ("tb_cab_vote", "tb_cab_vote 테이블명"),
    ("tb_freeze_window", "tb_freeze_window 테이블명"),
    ("rollback_plan", "롤백 계획 컬럼"),
    ("freeze_exempt", "동결 기간 예외 컬럼"),
    ("ci_ids_json", "영향받는 CI 목록 컬럼"),
    ("EMERGENCY", "긴급 변경 타입"),
    ("APPROVE", "CAB 승인 투표"),
]
for sym, desc in model_checks:
    status = "OK" if sym in models_src else "ERR"
    if status == "ERR":
        ok = False
    print(f"  {status}  {desc}")

print("\n=== 3. routers/change.py 엔드포인트 확인 ===")
with open("routers/change.py", encoding="utf-8") as f:
    router_src = f.read()

endpoint_checks = [
    ('@router.post("/rfc"', "POST /api/change/rfc"),
    ('@router.get("/rfc"', "GET /api/change/rfc"),
    ('@router.get("/rfc/{rfc_id}"', "GET /api/change/rfc/{id}"),
    ('@router.patch("/rfc/{rfc_id}"', "PATCH RFC"),
    ('@router.post("/rfc/{rfc_id}/submit"', "제출 (DRAFT→SUBMITTED)"),
    ('@router.post("/rfc/{rfc_id}/vote"', "CAB 투표"),
    ('@router.post("/rfc/{rfc_id}/decide"', "최종 결정"),
    ('@router.post("/rfc/{rfc_id}/schedule"', "일정 확정"),
    ('@router.post("/rfc/{rfc_id}/start"', "변경 시작"),
    ('@router.post("/rfc/{rfc_id}/complete"', "변경 완료"),
    ('@router.post("/rfc/{rfc_id}/fail"', "변경 실패"),
    ('@router.get("/rfc/{rfc_id}/votes"', "CAB 투표 현황"),
    ('@router.post("/freeze"', "동결 기간 등록"),
    ('@router.get("/freeze"', "동결 기간 목록"),
    ('@router.delete("/freeze/{freeze_id}"', "동결 기간 삭제"),
    ('@router.get("/freeze/check"', "동결 기간 확인"),
    ('@router.get("/calendar"', "변경 일정 캘린더"),
    ('@router.get("/stats"', "변경 통계"),
    ("_next_rfc_id", "RFC ID 생성 함수"),
    ("_check_freeze", "동결 기간 충돌 검사"),
    ("_count_votes", "투표 집계 함수"),
]
for sym, desc in endpoint_checks:
    status = "OK" if sym in router_src else "ERR"
    if status == "ERR":
        ok = False
    print(f"  {status}  {desc}")

print("\n=== 4. 상태 전환 흐름 검증 ===")
# RFC 상태 흐름: DRAFT→SUBMITTED→IN_REVIEW→(APPROVED|REJECTED)→SCHEDULED→IN_PROGRESS→(COMPLETED|FAILED)
state_flow = {
    "DRAFT":       "초안",
    "SUBMITTED":   "CAB 검토 제출",
    "IN_REVIEW":   "검토 중",
    "APPROVED":    "승인",
    "REJECTED":    "거부",
    "SCHEDULED":   "일정 확정",
    "IN_PROGRESS": "진행 중",
    "COMPLETED":   "완료",
    "FAILED":      "실패",
    "WITHDRAWN":   "철회",
}
try:
    import importlib.util
    spec = importlib.util.spec_from_file_location("models_mod", "models.py")
    models_mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(models_mod)

    rfc_statuses = set(e.value for e in models_mod.RFCStatus)
    for st, desc in state_flow.items():
        status = "OK" if st in rfc_statuses else "ERR"
        if status == "ERR":
            ok = False
        print(f"  {status}  RFCStatus.{st}: {desc}")

except Exception as e:
    print(f"  ERR  Enum 로드 오류: {type(e).__name__}: {e}")
    ok = False

print("\n=== 5. ChangeType / Risk / Vote Enum 검증 ===")
try:
    change_types = set(e.value for e in models_mod.ChangeType)
    for t in ["STANDARD", "NORMAL", "EMERGENCY", "MAJOR"]:
        status = "OK" if t in change_types else "ERR"
        if status == "ERR":
            ok = False
        print(f"  {status}  ChangeType.{t}")

    risk_levels = set(e.value for e in models_mod.ChangeRisk)
    for r in ["LOW", "MEDIUM", "HIGH", "CRITICAL"]:
        status = "OK" if r in risk_levels else "ERR"
        if status == "ERR":
            ok = False
        print(f"  {status}  ChangeRisk.{r}")

    vote_results = set(e.value for e in models_mod.CABVoteResult)
    for v in ["APPROVE", "REJECT", "ABSTAIN", "DEFER"]:
        status = "OK" if v in vote_results else "ERR"
        if status == "ERR":
            ok = False
        print(f"  {status}  CABVoteResult.{v}")

except Exception as e:
    print(f"  ERR  {type(e).__name__}: {e}")
    ok = False

print("\n=== 6. 변경 관리 비즈니스 규칙 검증 ===")
# 비즈니스 규칙이 코드에 구현되어 있는지 확인
rules = [
    ("rollback_plan", "롤백 계획 필수 체크 (submit 시)"),
    ("change_plan",   "변경 계획 필수 체크 (submit 시)"),
    ("freeze_exempt", "동결 기간 예외 처리"),
    ("_check_freeze", "동결 기간 충돌 검사 (schedule 시)"),
    ("is_final",      "최종 결정권자 투표"),
    ("approval_rate", "승인율 계산"),
    ("success_rate",  "변경 성공률 계산"),
    ("UserRole.ADMIN", "ADMIN 권한 검사 (decide)"),
    ("UserRole.PM",    "PM 권한 검사 (decide)"),
]
for sym, desc in rules:
    status = "OK" if sym in router_src else "ERR"
    if status == "ERR":
        ok = False
    print(f"  {status}  {desc}")

print("\n=== 7. RFC ID 형식 검증 ===")
from datetime import datetime
today = datetime.utcnow().strftime("%Y%m%d")
rfc_example = f"RFC-{today}-0001"
# RFC-YYYYMMDD-NNNN: 4+8+1+4 = 17자
try:
    assert rfc_example.startswith("RFC-"), "RFC ID 형식 오류"
    assert len(rfc_example) == 17, f"RFC ID 길이 오류: {len(rfc_example)}"
    print(f"  OK  RFC ID 형식: {rfc_example} ({len(rfc_example)}자)")
except AssertionError as e:
    print(f"  ERR  {e}")
    ok = False

print("\n=== 8. main.py 등록 확인 ===")
for sym, desc in [("change", "change 임포트"), ("change.router", "change 라우터 등록")]:
    status = "OK" if sym in open("main.py", encoding="utf-8").read() else "ERR"
    if status == "ERR":
        ok = False
    print(f"  {status}  {desc}")

print("\n=== C-2 변경 관리 CAB 테스트 완료 ===")
if ok:
    print("모든 검사 통과")
else:
    sys.exit(1)
