"""
youtube-check-new-transcripts.py 테스트

작업: task-192.1
목적: 유튜브 요약 대기 영상 감지 스크립트 동작 검증

참고: Firebase 연동 테스트는 task-190.1에서 검증된 TypeScript 스크립트를 사용.
      이 테스트는 Python 스크립트 자체의 로직 검증에 집중.
"""

import json
import pytest
import subprocess
from pathlib import Path
import tempfile


SCRIPT_PATH = Path("/home/jay/workspace/scripts/youtube-check-new-transcripts.py")
TRANSCRIPT_DIR = Path("/home/jay/workspace/memory/youtube-transcripts")
TS_SCRIPT_PATH = Path("/home/jay/projects/insuwiki/scripts/youtube-get-pending.ts")


class TestScriptExists:
    """스크립트 존재 여부 테스트"""

    def test_script_exists(self):
        """스크립트 파일이 존재하는지 확인"""
        assert SCRIPT_PATH.exists(), f"스크립트 파일이 없습니다: {SCRIPT_PATH}"

    def test_script_executable(self):
        """스크립트에 실행 권한이 있는지 확인"""
        assert SCRIPT_PATH.stat().st_mode & 0o111, "스크립트에 실행 권한이 없습니다"

    def test_script_syntax(self):
        """Python 문법 검증"""
        result = subprocess.run(
            ["python3", "-m", "py_compile", str(SCRIPT_PATH)],
            capture_output=True,
            text=True
        )
        assert result.returncode == 0, f"문법 오류: {result.stderr}"

    def test_ts_script_exists(self):
        """TypeScript 스크립트가 존재하는지 확인"""
        assert TS_SCRIPT_PATH.exists(), f"TypeScript 스크립트가 없습니다: {TS_SCRIPT_PATH}"


class TestScriptHelp:
    """도움말 테스트"""

    def test_help_output(self):
        """--help 옵션이 정상 동작하는지 확인"""
        result = subprocess.run(
            ["python3", str(SCRIPT_PATH), "--help"],
            capture_output=True,
            text=True,
            timeout=30
        )
        assert result.returncode == 0
        # argparse 표준 도움말 확인
        assert "usage:" in result.stdout.lower() or "optional arguments" in result.stdout.lower()


class TestArgumentValidation:
    """인자 검증 테스트"""

    def test_with_transcript_requires_video_id(self):
        """--with-transcript 옵션은 --video-id가 필요"""
        result = subprocess.run(
            ["python3", str(SCRIPT_PATH), "--with-transcript"],
            capture_output=True,
            text=True,
            timeout=30
        )
        
        # 에러로 종료해야 함
        assert result.returncode != 0, "--video-id 없이 --with-transcript 사용 시 에러여야 함"


class TestTranscriptSaveLogic:
    """전문 저장 로직 테스트 (subprocess 기반)"""

    def test_save_transcript_creates_file(self):
        """전문 저장 기능이 파일을 생성하는지 확인"""
        # 테스트용 임시 디렉토리 생성
        with tempfile.TemporaryDirectory() as tmpdir:
            test_file = Path(tmpdir) / "test_transcript.md"
            
            # 테스트용 마크다운 내용 생성
            content = f"""# 테스트 영상

- **채널**: 테스트 채널
- **영상 ID**: test_video_123
- **원본 URL**: https://www.youtube.com/watch?v=test_video_123

---

## 전문

이것은 테스트 전문입니다.
"""
            
            # 파일 생성
            with open(test_file, 'w', encoding='utf-8') as f:
                f.write(content)
            
            # 파일이 생성되었는지 확인
            assert test_file.exists(), "파일이 생성되어야 함"
            
            # 내용 확인
            with open(test_file, 'r', encoding='utf-8') as f:
                saved_content = f.read()
            
            assert "테스트 영상" in saved_content
            assert "test_video_123" in saved_content
            assert "https://www.youtube.com/watch?v=test_video_123" in saved_content

    def test_transcript_dir_path_exists(self):
        """전문 저장 디렉토리 경로가 유효한지 확인"""
        # 부모 디렉토리는 존재해야 함
        parent = TRANSCRIPT_DIR.parent
        assert parent.exists(), f"부모 디렉토리가 없습니다: {parent}"


class TestJsonOutput:
    """JSON 출력 형식 테스트"""

    def test_expected_json_structure_pending_list(self):
        """대기 영상 목록 JSON 구조 검증"""
        expected_keys = ["pendingCount", "videos"]
        
        # 예상 응답 구조
        sample = {
            "pendingCount": 0,
            "videos": []
        }
        
        for key in expected_keys:
            assert key in sample, f"JSON 응답에 '{key}' 키가 필요함"

    def test_expected_json_structure_video_item(self):
        """비디오 항목 JSON 구조 검증"""
        expected_video_keys = ["videoId", "title", "channelName"]
        
        sample_video = {
            "videoId": "abc123",
            "title": "테스트 영상",
            "channelName": "테스트 채널",
            "publishedAt": "2026-03-03",
            "hasTranscript": True,
            "driveTranscriptUrl": None,
            "transcriptionSource": "youtube_caption"
        }
        
        for key in expected_video_keys:
            assert key in sample_video, f"비디오 항목에 '{key}' 키가 필요함"

    def test_json_parsing_logic(self):
        """JSON 파싱 로직 테스트"""
        # 스크립트가 파싱해야 하는 형식의 JSON
        test_json = '{"pendingCount": 2, "videos": [{"videoId": "test1"}, {"videoId": "test2"}]}'
        
        parsed = json.loads(test_json)
        assert parsed["pendingCount"] == 2
        assert len(parsed["videos"]) == 2
        assert parsed["videos"][0]["videoId"] == "test1"


class TestTranscriptOutput:
    """전문 조회 출력 테스트"""

    def test_transcript_json_structure(self):
        """전문 조회 JSON 구조 검증"""
        expected_keys = ["videoId", "title", "channelName", "transcript"]
        
        sample = {
            "videoId": "test123",
            "title": "테스트 영상",
            "channelName": "테스트 채널",
            "transcript": "전문 내용..."
        }
        
        for key in expected_keys:
            assert key in sample, f"전문 JSON에 '{key}' 키가 필요함"

    def test_saved_transcript_json_structure(self):
        """저장된 전문 JSON 구조 검증"""
        # --save-transcript 사용 시 추가되는 필드
        sample_with_saved = {
            "videoId": "test123",
            "title": "테스트 영상",
            "channelName": "테스트 채널",
            "transcript": "전문 내용...",
            "savedTo": "/path/to/transcript.md"
        }
        
        assert "savedTo" in sample_with_saved


class TestScriptModules:
    """필요한 모듈 import 테스트"""

    def test_json_module(self):
        """json 모듈 사용 가능"""
        import json
        data = json.dumps({"test": "value"})
        assert json.loads(data) == {"test": "value"}

    def test_subprocess_module(self):
        """subprocess 모듈 사용 가능"""
        import subprocess
        result = subprocess.run(["echo", "test"], capture_output=True, text=True)
        assert result.returncode == 0

    def test_pathlib_module(self):
        """pathlib 모듈 사용 가능"""
        from pathlib import Path
        assert Path("/tmp").exists()

    def test_datetime_module(self):
        """datetime 모듈 사용 가능"""
        from datetime import datetime
        now = datetime.now()
        assert now.year >= 2024


class TestErrorHandling:
    """에러 처리 테스트"""

    def test_missing_ts_script_returns_error(self):
        """TypeScript 스크립트가 없을 때 에러 반환"""
        # 스크립트 내부에서 존재하지 않는 경로를 사용하면 에러를 반환해야 함
        # 이것은 간접적으로만 테스트 가능
        pass  # 실제 실행은 Firebase 환경 필요

    def test_invalid_json_handling(self):
        """잘못된 JSON 처리 테스트"""
        invalid_json = "not a valid json"
        
        try:
            json.loads(invalid_json)
            assert False, "JSONDecodeError가 발생해야 함"
        except json.JSONDecodeError:
            pass  # 정상


class TestIntegration:
    """통합 테스트"""

    def test_script_file_complete(self):
        """스크립트 파일이 완전한지 확인"""
        with open(SCRIPT_PATH, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 필수 함수/요소 확인
        assert "def main():" in content or "async def main():" in content
        assert "argparse" in content
        assert "subprocess" in content
        assert "json" in content
        assert "get_pending_videos" in content
        assert "get_transcript" in content
        assert "save_transcript" in content
        assert "run_ts_script" in content

    def test_script_constants(self):
        """스크립트 상수 확인"""
        with open(SCRIPT_PATH, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 필요한 경로 상수 확인
        assert "youtube-get-pending.ts" in content
        assert "youtube-transcripts" in content
        assert "insuwiki" in content


if __name__ == '__main__':
    pytest.main([__file__, '-v'])
