import re
import sys
from typing import Optional

KEYWORD_MAP = {
    r'\bcetak\b': 'print',
    r'\bmasukan\b': 'input',
    r'\bjangkauan\b': 'range',
    r'\bdengan\b': 'with',
    r'\bbuka\b': 'open',
    r'\bmodetulis\b': '"w"',
    r'\bmodebaca\b': '"r"',
    r'\bmodeambah\b': '"a"',
    r'\btulis\b': 'write',
    r'\bbaca\b': 'read',
    r'\bbacabarisan\b': 'readline',
    r'\bangka\b': 'int',
    r'\brangkaian\b': 'str',
    r'\bdesimal\b': 'float',
    r'\bdaftar\b': 'list',
    r'\bpasangan\b': 'tuple',
    r'\bpeta\b': 'dict',
    r'\bhimpunan\b': 'set',
    r'\bnilaisah\b': 'True',
    r'\bnilaisalah\b': 'False',
    r'\boraada\b': 'None',
    r'\btambah\b': 'append',
    r'\bbuang\b': 'pop',
    r'\burutkan\b': 'sort',
    r'\bbalikkandaftar\b': 'reverse',
    r'\bcari\b': 'find',
    r'\bganti\b': 'replace',
    r'\bbesar\b': 'upper',
    r'\bkecil\b': 'lower',
    r'\blamun\b': 'if',
    r'\blamunpo\b': 'elif',
    r'\bsajaba\b': 'else',
    r'\bulangi\b': 'for',
    r'\bselama\b': 'while',
    r'\bhentikan\b': 'break',
    r'\blanjutkeun\b': 'continue',
    r'\bfungsi\b': 'def',
    r'\bsoundhoreg\b': 'lambda',
    r'\bbalikin\b': 'return',
    r'\bkelas\b': 'class',
    r'\bobjek\b': 'object',
    r'\binisialisasi\b': '__init__',
    r'\bimpor\b': 'import',
    r'\bdari\b': 'from',
    r'\bkudu\b': 'assert',
    r'\bcoba\b': 'try',
    r'\bjikalausalah\b': 'except',
    r'\bjikalauselalu\b': 'finally',
    r'\bbangkitkeun\b': 'raise',
    r'\bjumlahkan\b': 'sum',
    r'\bpanjang\b': 'len',
    r'\bpalingkecil\b': 'min',
    r'\bpalingbesar\b': 'max',
    r'\bgabungan\b': 'join',
    r'\bpecah\b': 'split',
    r'\bdimiliki\b': 'in',
    r'\bsama\b': 'is',
    r'\bsebentar\b': 'pass'
}

def convert_sofinco_to_python(sofinco_code: str) -> str:
    python_code = sofinco_code
    for sofinco_keyword, python_keyword in KEYWORD_MAP.items():
        python_code = re.sub(sofinco_keyword, python_keyword, python_code)
    python_code = re.sub(r'\bsebagai\b', 'as', python_code)
    python_code = re.sub(r'\t', '    ', python_code)
    return python_code

def run_sofinco_file(file_path: str, save_converted: bool = True) -> None:
    if not file_path.endswith('.sofinco'):
        raise ValueError("❌ File harus memiliki ekstensi .sofinco!")
    
    with open(file_path, 'r', encoding='utf-8') as f:
        sofinco_code = f.read()
    
    python_code = convert_sofinco_to_python(sofinco_code)
    
    if save_converted:
        py_file_path = f"{file_path.rsplit('.', 1)[0]}.py"
        with open(py_file_path, 'w', encoding='utf-8') as f:
            f.write(python_code)
        print(f"💾 File Python hasil konversi disimpan di: {py_file_path}")
    
    try:
        exec(python_code, globals())
    except SyntaxError as e:
        raise Exception(f"❌ Error sintaks di baris {e.lineno}: {e.text.strip() if e.text else 'N/A'}") from e
    except Exception as e:
        raise Exception(f"❌ Error eksekusi: {str(e)}") from e

def main():
    import argparse
    parser = argparse.ArgumentParser(
        description='Sofinco - Bahasa Pemrograman Bahasa Makassar Berbasis Python',
        usage='sofinco <namafile.sofinco> [--tidaksimpan]',
        epilog='Contoh: sofinco program_saya.sofinco'
    )
    parser.add_argument('file', help='Path ke file program Sofinco (ekstensi .sofinco)')
    parser.add_argument('--tidaksimpan', action='store_false', dest='save_converted', 
                        help='Jangan menyimpan file Python hasil konversi')
    args = parser.parse_args()
    
    try:
        run_sofinco_file(args.file, args.save_converted)
        print("\n✅ Program Sofinco berjalan dengan sukses!")
    except Exception as e:
        print(f"\n{str(e)}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()

