#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
المترجم العربي المتقدم للغة Python
الإصدار 3.0 - يدعم التحويل إلى ملف بايثون، مع تحسين المسافات البادئة
"""

import sys
import re
import json
import os
import argparse
from typing import Dict, Any, List, Optional

# ----------------------------------------------------------------------
# تحميل قواعد التحويل من ملف JSON
# ----------------------------------------------------------------------
def load_rules(rules_file: Optional[str] = None) -> Dict[str, Any]:
    """
    تحميل قواعد التحويل. 
    إذا لم يتم تمرير مسار معين، سيتم البحث عن rules.json داخل مجلد المكتبة.
    """
    if rules_file is None or rules_file == "rules.json":
        # الحصول على المسار المطلق لمجلد المكتبة
        base_path = os.path.dirname(__file__)
        rules_file = os.path.join(base_path, "rules.json")
    
    if not os.path.exists(rules_file):
        raise FileNotFoundError(f"تعذر العثور على ملف القواعد في: {rules_file}")

    with open(rules_file, 'r', encoding='utf-8') as f:
        return json.load(f)



# ----------------------------------------------------------------------
# تحويل الكلمة العربية إلى لفظ إنجليزي (لأسماء المتغيرات والدوال)
# ----------------------------------------------------------------------
def arabic_to_translit(arabic_word: str) -> str:
    """
    تحويل الكلمة العربية إلى تمثيل صوتي باستخدام الأحرف الإنجليزية.
    يستخدم لتحويل أسماء المتغيرات والدوال التي تبقى عربية بعد استبدال الكلمات المفتاحية.
    """
    mapping = {
        'ا': 'a', 'أ': 'a', 'إ': 'e', 'آ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'j',
        'ح': 'h', 'خ': 'kh', 'د': 'd', 'ذ': 'dh', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh',
        'ص': 's', 'ض': 'd', 'ط': 't', 'ظ': 'z', 'ع': 'a', 'غ': 'gh', 'ف': 'f', 'ق': 'q',
        'ك': 'k', 'ل': 'l', 'م': 'm', 'ن': 'n', 'ه': 'h', 'ة': 'a', 'و': 'w', 'ي': 'y',
        'ى': 'a', 'ئ': 'e', 'ؤ': 'o', 'ء': '', ' ': '_', 'آ': 'aa'
    }
    result = []
    for char in arabic_word:
        if '\u0600' <= char <= '\u06FF':
            result.append(mapping.get(char, ''))
        else:
            result.append(char)
    translit = ''.join(result)
    translit = re.sub(r'_+', '_', translit)
    return translit.strip('_')


# ----------------------------------------------------------------------
# تحويل سطر واحد مع الحفاظ على السلاسل النصية
# ----------------------------------------------------------------------
def translate_line(line: str, rules: Dict[str, Any]) -> str:
    """
    تحويل سطر واحد مع عدم المساس بالنصوص المحصورة بين علامتي اقتباس.
    """
    leading_whitespace = re.match(r'^(\s*)', line).group(1)
    rest_of_line = line[len(leading_whitespace):]

    def transform_non_string(part: str) -> str:
        # استبدال الكلمات المفتاحية
        for eng, arabic_list in rules['keywords'].items():
            for arabic in arabic_list:
                pattern = r'(?<![A-Za-z\u0600-\u06FF0-9_])' + re.escape(arabic) + r'(?![A-Za-z\u0600-\u06FF0-9_])'
                part = re.sub(pattern, eng, part)

        # تحويل الأسماء العربية (المعرفات) إلى تمثيل صوتي
        def replace_arabic_identifier(match):
            word = match.group(0)
            if any('\u0600' <= c <= '\u06FF' for c in word):
                return arabic_to_translit(word)
            return word

        identifier_pattern = r'[A-Za-z\u0600-\u06FF_][A-Za-z\u0600-\u06FF0-9_]*'
        part = re.sub(identifier_pattern, replace_arabic_identifier, part)
        return part

    # نمط للتعرف على السلاسل النصية
    string_pattern = r'("[^"\\]*(\\.[^"\\]*)*"|\'[^\'\\]*(\\.[^\'\\]*)*\')'

    parts = []
    last_end = 0
    for match in re.finditer(string_pattern, rest_of_line):
        start, end = match.start(), match.end()
        if start > last_end:
            non_string = rest_of_line[last_end:start]
            parts.append(transform_non_string(non_string))
        parts.append(rest_of_line[start:end])
        last_end = end
    if last_end < len(rest_of_line):
        non_string = rest_of_line[last_end:]
        parts.append(transform_non_string(non_string))

    translated_rest = ''.join(parts)
    return leading_whitespace + translated_rest


# ----------------------------------------------------------------------
# تحويل ملف كامل إلى كود بايثون
# ----------------------------------------------------------------------
def convert_file(input_file: str, rules: Dict[str, Any]) -> List[str]:
    """
    يقرأ ملفاً عربياً ويحوله إلى قائمة أسطر بايثون.
    """
    with open(input_file, 'r', encoding='utf-8') as f:
        arabic_lines = f.readlines()

    python_lines = []
    for line in arabic_lines:
        stripped_line = line.rstrip('\n')
        if stripped_line.strip() == '':
            python_lines.append('')
        else:
            translated = translate_line(stripped_line, rules)
            python_lines.append(translated)

    return python_lines


# ----------------------------------------------------------------------
# تنفيذ كود بايثون (من قائمة أسطر)
# ----------------------------------------------------------------------
def execute_python_code(python_lines: List[str]) -> None:
    """
    تنفيذ الكود المحول.
    """
    python_code = '\n'.join(python_lines)
    try:
        exec(python_code, {'__name__': '__main__'})
    except Exception as e:
        print(f"خطأ أثناء التنفيذ: {e}", file=sys.stderr)
        # اختياري: عرض الكود المحول عند الخطأ
        # print("=== الكود المحول ===")
        # print(python_code)


# ----------------------------------------------------------------------
# كتابة الكود المحول إلى ملف
# ----------------------------------------------------------------------
def write_output(python_lines: List[str], output_file: str) -> None:
    """
    كتابة الكود المحول إلى ملف بايثون.
    """
    with open(output_file, 'w', encoding='utf-8') as f:
        f.write('\n'.join(python_lines))
    print(f"تم تحويل الملف إلى: {output_file}")


# ----------------------------------------------------------------------
# الوضع التفاعلي
# ----------------------------------------------------------------------
def interactive_mode():
    """
    وضع تفاعلي: يسمح بكتابة كود عربي سطراً سطراً وتنفيذه فوراً.
    """
    rules = load_rules()
    print("--- الوضع التفاعلي للمترجم العربي ---")
    print("اكتب كود عربي سطراً سطراً، وسيتم تنفيذه مباشرة.")
    print("لإنهاء الجلسة اكتب 'خروج' أو 'exit'.")

    accumulated_code = []
    while True:
        try:
            line = input("<<< ")
        except EOFError:
            break

        if line.strip() in ("خروج", "exit"):
            break

        if line.strip() == '':
            continue

        # ترجمة السطر
        translated = translate_line(line, rules)
        accumulated_code.append(translated)

        # محاولة تنفيذ الكود المتراكم حتى الآن
        try:
            code_to_run = '\n'.join(accumulated_code)
            exec(code_to_run, {'__name__': '__main__'})
        except Exception as e:
            print(f"خطأ: {e}")


# ----------------------------------------------------------------------
# الوظيفة الرئيسية
# ----------------------------------------------------------------------
def main():
    parser = argparse.ArgumentParser(description="مترجم عربي لبايثون")
    parser.add_argument("input", nargs="?", help="ملف الإدخال العربي (.ar)")
    parser.add_argument("-o", "--output", help="ملف الإخراج بايثون (إذا لم يُعطَ، يتم إنشاء ملف بجانب الأصلي)")
    parser.add_argument("-r", "--rules", default="rules.json", help="ملف القواعد (افتراضي: rules.json)")
    parser.add_argument("-i", "--interactive", action="store_true", help="تشغيل الوضع التفاعلي")
    parser.add_argument("--no-exec", action="store_true", help="لا تنفذ الكود بعد التحويل (فقط حول إلى ملف)")
    parser.add_argument("--exec-only", action="store_true", help="نفذ فقط دون إنشاء ملف")

    args = parser.parse_args()

    # إذا طلب الوضع التفاعلي، ندخله فوراً
    if args.interactive:
        interactive_mode()
        return

    # إذا لم يُعطَ ملف إدخال، نعرض المساعدة
    if not args.input:
        parser.print_help()
        sys.exit(1)

    # تحميل القواعد
    try:
        rules = load_rules(args.rules)
    except Exception as e:
        print(f"خطأ في تحميل القواعد: {e}")
        sys.exit(1)

    # تحويل الملف
    try:
        python_lines = convert_file(args.input, rules)
    except Exception as e:
        print(f"خطأ في قراءة الملف {args.input}: {e}")
        sys.exit(1)

    # تنفيذ الكود إذا لم يطلب المستخدم عدم التنفيذ
    if not args.no_exec:
        execute_python_code(python_lines)
        

    # إنشاء ملف الإخراج إذا لم يطلب التنفيذ فقط
    if not args.exec_only:
        # تحديد اسم ملف الإخراج
        if args.output:
            output_file = args.output
            write_output(python_lines, output_file)
            
        else:
            # استبدال الامتداد بـ .py أو إضافته
            base, ext = os.path.splitext(args.input)
            if ext.lower() in ['.ay', '.arabic']:
                output_file = base + '.py'
                
            else:
                #output_file = args.input + '.py'
                execute_python_code(python_lines)

        #write_output(python_lines, output_file)
     #   execute_python_code(python_lines)
       # print("hhhhhh")


if __name__ == "__main__":
    main()