# -*- coding: utf-8 -*-
"""
metadata.json 读写与去字幕后更新（含跨进程文件锁，与 Java MarkerExportService 一致）。
"""
import json
import logging
from pathlib import Path
from typing import List, Dict, Any

logger = logging.getLogger(__name__)


def load_metadata(metadata_path: str) -> Dict[str, Any]:
    with open(metadata_path, "r", encoding="utf-8") as f:
        data = json.load(f)
    return data


def save_metadata(metadata_path: str, data: dict) -> None:
    tmp = metadata_path + ".tmp"
    with open(tmp, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    Path(tmp).replace(metadata_path)


def get_processed_chunks(data: dict) -> List[Dict[str, Any]]:
    chunks = data.get("chunks") or []
    return [c for c in chunks if c.get("status") == "processed"]


def get_pending_chunks(data: dict) -> List[Dict[str, Any]]:
    chunks = data.get("chunks") or []
    return [c for c in chunks if c.get("status") in ("pending", "failed")]


def update_chunk_processed(metadata_path: str, chunk_id: str, processed_path: str) -> None:
    """将指定 chunk 标记为已处理并写入 processedPath；同目录校验 + 文件锁防串片与并发丢失。"""
    meta_path = Path(metadata_path)
    processed_path_obj = Path(processed_path)
    meta_dir = meta_path.parent.resolve()
    processed_dir = processed_path_obj.parent.resolve()
    if meta_dir != processed_dir:
        logger.error("串片防护: processedPath 与 metadata 不在同一目录, meta_dir=%s, processed_dir=%s, chunk_id=%s",
                     meta_dir, processed_dir, chunk_id)
        raise ValueError("processedPath 必须与 metadata.json 同目录，防止串片")

    lock_path = Path(metadata_path + ".lock")
    lock_path.parent.mkdir(parents=True, exist_ok=True)
    try:
        import fcntl
        _use_flock = True
    except ImportError:
        _use_flock = False  # Windows 无 fcntl，单进程或接受并发风险

    def _do_update():
        data = load_metadata(metadata_path)
        # 存相对路径（相对 metadata 所在目录），便于移动 output 目录后仍可合并
        rel_path = processed_path_obj.name
        for chunk in data.get("chunks") or []:
            if chunk.get("chunkId") == chunk_id:
                chunk["processedPath"] = rel_path
                chunk["status"] = "processed"
                chunk["processedAt"] = __import__("datetime").datetime.utcnow().isoformat() + "Z"
                save_metadata(metadata_path, data)
                logger.info("已更新 metadata 中 chunk %s 为已处理: %s", chunk_id, rel_path)
                return
        logger.warning("未在 metadata 中找到 chunk: %s", chunk_id)

    if _use_flock:
        with open(lock_path, "w") as lock_file:
            fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX)
            try:
                _do_update()
            finally:
                fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
        try:
            lock_path.unlink(missing_ok=True)
        except OSError:
            pass
    else:
        _do_update()
