#!/usr/bin/env python3
"""
Script to check PO translation files for compliance with "Do not translate" comments.
Traverses all .po files in the working directory and reports missing untranslated terms.
"""

import os
import re
import polib
from pathlib import Path


def extract_no_translate_terms(comment):
    """
    Extract terms that should not be translated from a translation note comment.
    
    Args:
        comment (str): The comment text
        
    Returns:
        list: List of terms that should not be translated
    """
    if "Translation note:" not in comment or "Do not translate" not in comment:
        return []
    
    # Handle the special case: "Do not translate "Execute". Translate "Opt." as "Option" here"
    if 'Translate "' in comment and '" as "' in comment:
        # Extract only the part before the "Translate ... as ..." instruction
        do_not_translate_part = comment.split('Translate "')[0]
        quoted_terms = re.findall(r'"([^"]+)"', do_not_translate_part)
        return quoted_terms
    
    # For general case, find all quoted terms after "Do not translate"
    do_not_translate_index = comment.find("Do not translate")
    if do_not_translate_index == -1:
        return []
    
    # Extract the part after "Do not translate"
    relevant_part = comment[do_not_translate_index:]

    # Cut at the first period if there's more text following it
    if "." in relevant_part:
        first_sentence, rest = relevant_part.split(".", 1)
        if rest.strip():  # there *is* something after the period
            relevant_part = first_sentence

    quoted_terms = re.findall(r'"([^"]+)"', relevant_part)
    
    # If no quoted terms found, skip this entry (e.g., "Do not translate" without specific terms)
    if not quoted_terms:
        return []
    
    return quoted_terms

def normalize_msgstr(s: str) -> str:
    """
    Normalize a msgstr for compliance checking:
    - Remove underscores used as mnemonics.
    - Preserve underscores in 'WM_CLASS'.
    """
    # Temporary placeholder to protect WM_CLASS
    protected = s.replace("WM_CLASS", "WMCLASSPROTECTED")
    # Remove all underscores
    protected = protected.replace("_", "")
    # Restore WM_CLASS
    return protected.replace("WMCLASSPROTECTED", "WM_CLASS").lower()

def check_entry_compliance(entry):
    """
    Check if a PO entry complies with translation notes.
    
    Args:
        entry: polib entry object
        
    Returns:
        tuple: (is_compliant, missing_terms, no_translate_terms)
    """
    if not entry.msgstr or not entry.comment:
        return True, [], []
    
    # Extract terms that should not be translated
    no_translate_terms = extract_no_translate_terms(entry.comment)
    if not no_translate_terms:
        return True, [], []
    
    # Normalize translation
    msgstr_normalized = normalize_msgstr(entry.msgstr)
    
    missing_terms = []
    for term in no_translate_terms:
        if term.lower() not in msgstr_normalized:
            missing_terms.append(term)
    
    is_compliant = len(missing_terms) == 0
    return is_compliant, missing_terms, no_translate_terms

def check_po_file(filepath):
    """
    Check a single PO file for translation compliance.
    
    Args:
        filepath (str): Path to the PO file
        
    Returns:
        list: List of error dictionaries
    """
    errors = []
    
    try:
        po = polib.pofile(filepath)
        
        for entry in po:
            is_compliant, missing_terms, no_translate_terms = check_entry_compliance(entry)
            
            if not is_compliant:
                errors.append({
                    'file': filepath,
                    'line': entry.linenum,
                    'msgid': entry.msgid,
                    'msgstr': entry.msgstr,
                    'missing_terms': missing_terms,
                    'required_terms': no_translate_terms,
                    'comment': entry.comment
                })
                
    except Exception as e:
        print(f"Error processing file {filepath}: {e}")
        
    return errors

def find_po_files(directory="../../po"):
    """
    Find all .po files in the given directory.
    
    Args:
        directory (str): Directory to search in
        
    Returns:
        list: List of .po file paths
    """
    po_files = []
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith('.po'):
                po_files.append(os.path.join(root, file))
    return po_files

def main():
    """
    Main function to check all PO files in the working directory.
    """
    print("Checking PO translation files for compliance...")
    print("=" * 60)
    
    # Find all PO files
    po_files = find_po_files()
    
    if not po_files:
        print("No .po files found in the current directory.")
        return
    
    print(f"Found {len(po_files)} PO file(s)")
    print()
    
    total_errors = 0
    
    for po_file in po_files:
        errors = check_po_file(po_file)
        
        if errors:
            print(f"Checking: {po_file}")
            print(f"  ❌ Found {len(errors)} error(s)")
            total_errors += len(errors)
            
            for error in errors:
                print(f"    Line {error['line']}:")
                print(f"      Missing terms: {', '.join(error['missing_terms'])}")
                print(f"      Required terms: {', '.join(error['required_terms'])}")
                print(f"      msgid: {error['msgid'][:80]}{'...' if len(error['msgid']) > 80 else ''}")
                print(f"      msgstr: {error['msgstr'][:80]}{'...' if len(error['msgstr']) > 80 else ''}")
                print()
            
            print()
    
    print("=" * 60)
    print(f"Summary: {total_errors} total error(s) found across {len(po_files)} file(s)")
    
    if total_errors > 0:
        print("\nErrors indicate that required untranslated terms are missing from translations.")
        print("Please review the msgstr entries and ensure the specified terms remain untranslated.")


if __name__ == "__main__":
    # Check if polib is available
    try:
        import polib
    except ImportError:
        print("Error: polib is required but not installed.")
        print("Install it with: pip install polib")
        exit(1)
    
    main()
