#!/usr/bin/env python3
"""
task-1934: 네이버 블로그 글 작성 E2E 실제 테스트
아르고스 QA 테스터 - InsurWiki 프로젝트
"""

import requests
import time
import sys

BASE_URL = "http://localhost:8000"
TIMEOUT = 30  # 단일 요청 타임아웃
POLL_INTERVAL = 5  # 폴링 간격 (초)
MAX_POLL_SECONDS = 180  # 최대 폴링 시간

results = []


def log(msg):
    print(msg, flush=True)


def record(tc, passed, detail=""):
    status = "PASS" if passed else "FAIL"
    results.append((tc, status, detail))
    indicator = "✓" if passed else "✗"
    log(f"[{status}] {tc} {indicator}  {detail}")


# ---------------------------------------------------------------------------
# TC-1: 키워드 분석 → 글 생성 풀 플로우
# ---------------------------------------------------------------------------
def tc1_full_flow():
    log("\n" + "=" * 60)
    log("TC-1: 키워드 분석 → 글 생성 풀 플로우")
    log("=" * 60)

    # Step 1: 키워드 분석
    log("\n[Step 1] POST /api/naver-blog/keyword-analysis")
    try:
        r = requests.post(
            f"{BASE_URL}/api/naver-blog/keyword-analysis",
            json={"keyword": "실손보험 청구 방법"},
            timeout=TIMEOUT,
        )
    except Exception as e:
        record("TC-1 키워드분석 HTTP", False, str(e))
        return None

    if r.status_code != 200:
        record("TC-1 키워드분석 HTTP", False, f"status={r.status_code}")
        return None
    record("TC-1 키워드분석 HTTP", True, f"status=200")

    data = r.json()
    results_list = data.get("results", [])
    if not results_list:
        record("TC-1 results 비어있지않음", False, "results 배열이 비어있음")
        return None
    record("TC-1 results 비어있지않음", True, f"results 개수={len(results_list)}")

    analysis_id = data.get("analysis_id")
    if analysis_id is None:
        record("TC-1 analysis_id 확인", False, "analysis_id 없음")
    else:
        record("TC-1 analysis_id 확인", True, f"analysis_id={analysis_id}")

    # Step 4: 추천 키워드 상위 3개 추출
    recommended = data.get("recommended", [])
    if not recommended:
        recommended = results_list  # fallback
    keywords = [item["relKeyword"] for item in recommended[:3]]
    log(f"\n[Step 4] 추천 키워드 상위 3개: {keywords}")

    # Step 5: 글 생성 시작
    log("\n[Step 5] POST /api/naver-blog/generate")
    try:
        r2 = requests.post(
            f"{BASE_URL}/api/naver-blog/generate",
            json={
                "keywords": keywords,
                "additionalContent": "",
                "tone": "mixed",
                "model": "haiku",
            },
            timeout=TIMEOUT,
        )
    except Exception as e:
        record("TC-1 글생성 시작 HTTP", False, str(e))
        return None

    if r2.status_code != 200:
        record("TC-1 글생성 시작 HTTP", False, f"status={r2.status_code}, body={r2.text[:200]}")
        return None
    record("TC-1 글생성 시작 HTTP", True, f"status=200")

    gen_data = r2.json()
    started = gen_data.get("status") == "started"
    record("TC-1 status=started 확인", started, f"status={gen_data.get('status')}")
    if not started:
        return None

    # Step 7: 폴링
    log(f"\n[Step 7] GET /api/naver-blog/write/status 폴링 (최대 {MAX_POLL_SECONDS}초)")
    generated_content = ""
    start_time = time.time()
    poll_count = 0
    final_status = "unknown"

    while time.time() - start_time < MAX_POLL_SECONDS:
        poll_count += 1
        elapsed = int(time.time() - start_time)
        try:
            rs = requests.get(
                f"{BASE_URL}/api/naver-blog/write/status",
                timeout=TIMEOUT,
            )
        except Exception as e:
            log(f"  폴링 오류: {e}")
            time.sleep(POLL_INTERVAL)
            continue

        if rs.status_code != 200:
            log(f"  폴링 HTTP 오류: {rs.status_code}")
            time.sleep(POLL_INTERVAL)
            continue

        status_data = rs.json()
        current_status = status_data.get("status", "unknown")
        progress = status_data.get("progress", 0)
        current_step = status_data.get("currentStep", "")
        log(f"  [{elapsed}s] 폴 #{poll_count}: status={current_status}, progress={progress}%, step={current_step}")

        if current_status == "completed":
            final_status = "completed"
            generated_content = status_data.get("generatedContent", "")
            break
        elif current_status == "failed":
            final_status = "failed"
            log(f"  ERROR: {status_data.get('error', '알 수 없는 오류')}")
            break

        time.sleep(POLL_INTERVAL)

    # Step 8: completed 확인
    record("TC-1 status=completed 도달", final_status == "completed", f"final_status={final_status}")

    # Step 9: generatedContent 비어있지 않음
    content_ok = bool(generated_content and len(generated_content) > 0)
    record("TC-1 generatedContent 비어있지않음", content_ok, f"길이={len(generated_content)}")

    if not content_ok:
        return None

    # Step 10: 글 품질 확인
    has_korean = any("\uAC00" <= c <= "\uD7A3" for c in generated_content)
    record("TC-1 한글 포함", has_korean)

    has_structure = any(marker in generated_content for marker in ["#", "##", "###", "\n\n"])
    record("TC-1 제목/소제목 구조 존재", has_structure)

    length_ok = len(generated_content) >= 1000
    record("TC-1 1000자 이상", length_ok, f"실제 길이={len(generated_content)}자")

    # 생성된 글 앞 500자 출력
    log("\n--- 생성된 글 앞 500자 ---")
    log(generated_content[:500])
    log("--- (이하 생략) ---")

    return generated_content


# ---------------------------------------------------------------------------
# TC-2: 히스토리 기록 확인
# ---------------------------------------------------------------------------
def tc2_history():
    log("\n" + "=" * 60)
    log("TC-2: 히스토리 기록 확인")
    log("=" * 60)

    try:
        r = requests.get(
            f"{BASE_URL}/api/naver-blog/history/contents",
            timeout=TIMEOUT,
        )
    except Exception as e:
        record("TC-2 히스토리 HTTP", False, str(e))
        return

    if r.status_code != 200:
        record("TC-2 히스토리 HTTP", False, f"status={r.status_code}")
        return
    record("TC-2 히스토리 HTTP", True, f"status=200")

    data = r.json()
    # 응답이 리스트이거나 {"contents": [...]} 형태일 수 있음
    if isinstance(data, list):
        items = data
    elif isinstance(data, dict):
        items = data.get("contents", data.get("items", data.get("results", [])))
    else:
        items = []

    if not items:
        record("TC-2 히스토리 항목 존재", False, "항목 없음")
        return
    record("TC-2 히스토리 항목 존재", True, f"항목 수={len(items)}")

    latest = items[0]
    log(f"\n최신 항목: {latest}")
    status_val = latest.get("status", "")
    record("TC-2 최신 항목 status=success", status_val == "success", f"status={status_val}")


# ---------------------------------------------------------------------------
# TC-3: 에러 핸들링 (잘못된 모델)
# ---------------------------------------------------------------------------
def tc3_invalid_model():
    log("\n" + "=" * 60)
    log("TC-3: 에러 핸들링 (잘못된 모델)")
    log("=" * 60)

    try:
        r = requests.post(
            f"{BASE_URL}/api/naver-blog/generate",
            json={"keywords": ["테스트"], "model": "invalid_model"},
            timeout=TIMEOUT,
        )
    except Exception as e:
        record("TC-3 잘못된 모델 400", False, str(e))
        return

    log(f"응답 status={r.status_code}, body={r.text[:200]}")
    record("TC-3 잘못된 모델 HTTP 400", r.status_code == 400, f"status={r.status_code}")


# ---------------------------------------------------------------------------
# TC-4: 키워드 없이 글 생성 시도
# ---------------------------------------------------------------------------
def tc4_empty_keywords():
    log("\n" + "=" * 60)
    log("TC-4: 키워드 없이 글 생성 시도")
    log("=" * 60)

    try:
        r = requests.post(
            f"{BASE_URL}/api/naver-blog/generate",
            json={"keywords": []},
            timeout=TIMEOUT,
        )
    except Exception as e:
        record("TC-4 빈 키워드 400", False, str(e))
        return

    log(f"응답 status={r.status_code}, body={r.text[:200]}")
    record("TC-4 빈 키워드 HTTP 400", r.status_code == 400, f"status={r.status_code}")


# ---------------------------------------------------------------------------
# 메인
# ---------------------------------------------------------------------------
if __name__ == "__main__":
    log("=" * 60)
    log("InsurWiki 네이버 블로그 E2E 테스트 시작")
    log(f"대상 서버: {BASE_URL}")
    log("=" * 60)

    tc1_full_flow()
    tc2_history()
    tc3_invalid_model()
    tc4_empty_keywords()

    # 결과 요약
    log("\n" + "=" * 60)
    log("테스트 결과 요약")
    log("=" * 60)
    passed = sum(1 for _, s, _ in results if s == "PASS")
    failed = sum(1 for _, s, _ in results if s == "FAIL")
    for tc, status, detail in results:
        indicator = "✓" if status == "PASS" else "✗"
        log(f"  [{status}] {indicator}  {tc}  {detail}")

    log(f"\n총 {len(results)}개 항목: PASS={passed}, FAIL={failed}")
    if failed == 0:
        log("모든 테스트 통과!")
    else:
        log(f"{failed}개 항목 실패.")
    sys.exit(0 if failed == 0 else 1)
