#!/usr/bin/env python3
"""
Check .po files for untranslated strings.
Reports entries where msgstr is empty OR msgstr equals msgid.
"""

import os
import re
import sys
from pathlib import Path

# Fix Windows console encoding for Unicode output
if sys.platform == 'win32':
    sys.stdout.reconfigure(encoding='utf-8', errors='replace')

SCRIPT_DIR = Path(__file__).parent
TRUNCATE_LEN = 50


def parse_po_string(lines: list[str], start_idx: int) -> tuple[str, int]:
    """Parse a quoted string (msgid or msgstr) from lines. Returns (value, next_line_idx)."""
    if start_idx >= len(lines):
        return "", start_idx
    line = lines[start_idx]
    match = re.match(r'^(msgid|msgstr|msgid_plural|msgstr\[\d+\])\s+"(.*)"\s*$', line)
    if not match:
        return "", start_idx
    value = match.group(2).replace('\\n', '\n').replace('\\"', '"')
    idx = start_idx + 1
    while idx < len(lines):
        cont = lines[idx]
        if not cont.startswith('"') or not cont.rstrip().endswith('"'):
            break
        inner = cont.strip()[1:-1].replace('\\n', '\n').replace('\\"', '"')
        value += inner
        idx += 1
    return value, idx


def parse_po_file(filepath: Path) -> list[dict]:
    """Parse a .po file and return list of entries."""
    content = filepath.read_text(encoding='utf-8')
    lines = content.split('\n')
    entries = []
    i = 0
    while i < len(lines):
        line = lines[i]
        if line.strip().startswith('#'):
            i += 1
            continue
        if re.match(r'^\s*msgid\s+', line):
            msgid, i = parse_po_string(lines, i)
            msgid_plural = None
            msgstrs = []
            while i < len(lines):
                nline = lines[i]
                if re.match(r'^\s*msgid_plural\s+', nline):
                    msgid_plural, i = parse_po_string(lines, i)
                elif re.match(r'^\s*msgstr\[\d+\]\s+', nline):
                    s, i = parse_po_string(lines, i)
                    msgstrs.append(s)
                elif re.match(r'^\s*msgstr\s+', nline):
                    s, i = parse_po_string(lines, i)
                    msgstrs = [s]
                    break
                elif re.match(r'^\s*msgid\s+', nline) or (nline.strip() == '' and i + 1 < len(lines) and re.match(r'^\s*#', lines[i + 1])):
                    break
                else:
                    i += 1
            if msgid_plural is not None and not msgstrs:
                msgstrs = ['', '']
            entries.append({
                'msgid': msgid,
                'msgid_plural': msgid_plural,
                'msgstrs': msgstrs,
            })
            continue
        i += 1
    return entries


def is_untranslated(entry: dict) -> bool:
    """Check if entry is untranslated: empty msgstr or msgstr equals msgid."""
    if not entry['msgstrs']:
        return True
    if entry['msgid_plural'] is not None:
        refs = [entry['msgid'], entry['msgid_plural']]
        for j, s in enumerate(entry['msgstrs']):
            if not s or (j < len(refs) and s == refs[j]):
                return True
        return False
    s = entry['msgstrs'][0]
    return not s or s == entry['msgid']


def truncate(s: str, max_len: int = TRUNCATE_LEN) -> str:
    """Truncate string and add ellipsis if needed."""
    s = s.replace('\n', ' ')
    if len(s) <= max_len:
        return s
    return s[: max_len - 3] + '...'


def main():
    po_files = sorted(SCRIPT_DIR.glob('chess-podium-*.po'))
    if not po_files:
        print("No .po files found in", SCRIPT_DIR)
        return
    for po_path in po_files:
        lang = po_path.stem.replace('chess-podium-', '')
        entries = parse_po_file(po_path)
        untranslated = []
        for e in entries:
            if e['msgid'] == '':
                continue
            if is_untranslated(e):
                untranslated.append(e['msgid'])
        print(f"\n=== {po_path.name} ({lang}) ===")
        print(f"Untranslated: {len(untranslated)} / {len([e for e in entries if e['msgid']])}")
        for msgid in untranslated:
            print(f"  - {truncate(msgid)}")


if __name__ == '__main__':
    main()
