# -*- coding: utf-8 -*-
"""
7945db Database Modülü
Otomatik olarak database.7945d'den çevrildi
"""

import os
import json
import hashlib
from datetime import datetime
from typing import Dict, Any, Optional, Union, List
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes

class Database7945:
    def __init__(self):
        """7945db Database sınıfı"""
        self.tables: Dict[str, Dict] = {}
        self.functions: Dict[str, Any] = {}
        self.current_file: Optional[str] = None
        self.auto_save: bool = True
        
        # Ana şifreleme anahtarı
        self.master_key = self._generate_master_key()
        
        # Çekirdek fonksiyonları başlat
        self._init_core_functions()
    
    def _generate_master_key(self) -> bytes:
        """Ana şifreleme anahtarını oluştur"""
        import secrets
        return secrets.token_bytes(32)
    
    def file(self, file_path: str) -> 'Database7945':
        """Database dosyasını ayarlar"""
        if not file_path.endswith('.7945db'):
            raise ValueError("Geçersiz dosya uzantısı. .7945db dosyası gerekiyor.")
        
        self.current_file = file_path
        
        if os.path.exists(file_path):
            self._load_from_file(file_path)
        else:
            self._save_to_file()
        
        return self
    
    def add(self, **kwargs) -> 'Database7945':
        """Veri ekler"""
        if not self.current_file:
            raise ValueError("Önce database dosyası belirtin: db.file('./db.7945db')")
        
        data_type = kwargs.get('type')
        
        if data_type == 'table':
            self._add_table(kwargs.get('name'))
        elif data_type == 'variable':
            self._add_variable(
                kwargs.get('table'),
                kwargs.get('name'),
                kwargs.get('value'),
                kwargs.get('cstm_value', 'none')
            )
        else:
            raise ValueError(f"Bilinmeyen tip: {data_type}")
        
        if self.auto_save:
            self._save_to_file()
        
        return self
    
    def get(self, **kwargs) -> Any:
        """Veri okur"""
        table = kwargs.get('table')
        name = kwargs.get('name')
        
        if table in self.tables and name in self.tables[table].get('variables', {}):
            return self.tables[table]['variables'][name]['value']
        raise ValueError(f"Değişken bulunamadı: {table}.{name}")
    
    def set(self, table: str, name: str, value: Any) -> 'Database7945':
        """Değer günceller"""
        if table in self.tables and name in self.tables[table].get('variables', {}):
            self.tables[table]['variables'][name]['value'] = value
            self.tables[table]['variables'][name]['lastModified'] = datetime.now().isoformat()
            
            if self.auto_save:
                self._save_to_file()
            return self
        raise ValueError(f"Değişken bulunamadı: {table}.{name}")
    
    def show(self) -> 'Database7945':
        """Database'i gösterir"""
        print('\n=== 7945 DATABASE ===')
        for table_name, table in self.tables.items():
            print(f'\n{table_name}:')
            for var_name, variable in table.get('variables', {}).items():
                print(f'  {var_name}: {variable.get("value")}')
        print('\n=====================\n')
        return self
    
    def _add_table(self, name: str):
        """Tablo ekler"""
        if name not in self.tables:
            self.tables[name] = {
                'variables': {},
                'created': datetime.now().isoformat()
            }
    
    def _add_variable(self, table: str, name: str, value_type: str, custom_value: str = "none"):
        """Değişken ekler"""
        if table not in self.tables:
            self._add_table(table)
        
        value = custom_value if custom_value != "none" else (
            0 if value_type == 'num' else
            False if value_type == 'bool' else ""
        )
        
        self.tables[table]['variables'][name] = {
            'value': value,
            'type': value_type,
            'lastModified': datetime.now().isoformat()
        }
    
    def _save_to_file(self):
        """Database'i dosyaya kaydeder"""
        if not self.current_file:
            return
        
        data = {
            'tables': self.tables,
            'metadata': {
                'created': datetime.now().isoformat(),
                'version': '1.0.0'
            }
        }
        
        encrypted = self._encrypt_data(json.dumps(data))
        
        with open(self.current_file, 'wb') as f:
            f.write(encrypted)
    
    def _load_from_file(self, file_path: str):
        """Database'i dosyadan yükler"""
        try:
            with open(file_path, 'rb') as f:
                encrypted = f.read()
            
            decrypted = self._decrypt_data(encrypted)
            data = json.loads(decrypted)
            self.tables = data.get('tables', {})
        except Exception:
            self.tables = {}
    
    def _encrypt_data(self, data: str) -> bytes:
        """Veriyi şifreler"""
        # AES-256-CBC şifreleme
        key = hashlib.sha256(b'7945db-secret').digest()
        iv = get_random_bytes(16)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        
        padded_data = pad(data.encode('utf-8'), AES.block_size)
        encrypted = cipher.encrypt(padded_data)
        
        return iv + encrypted
    
    def _decrypt_data(self, encrypted: bytes) -> str:
        """Şifreli veriyi çözer"""
        try:
            key = hashlib.sha256(b'7945db-secret').digest()
            iv = encrypted[:16]
            ciphertext = encrypted[16:]
            
            cipher = AES.new(key, AES.MODE_CBC, iv)
            decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size)
            
            return decrypted.decode('utf-8')
        except Exception:
            raise ValueError('Database dosyası okunamıyor')
    
    def _init_core_functions(self):
        """Çekirdek fonksiyonları başlatır"""
        # Temel fonksiyonlar
        self.functions['add.json.table'] = self._add_json_table
        self.functions['add.json.var'] = self._add_json_var
        self.functions['edit.var'] = self._edit_var
        self.functions['remove.var'] = self._remove_var
    
    def _add_json_table(self, table_name: str):
        """JSON tablosu ekler"""
        if table_name not in self.tables:
            self.tables[table_name] = {
                'variables': {},
                'created': datetime.now().isoformat(),
                'tableId': len(self.tables) + 1,
                'tableIndex': len(self.tables) + 1
            }
        return self.tables[table_name]
    
    def _add_json_var(self, table_name: str, var_name: str, var_value: Any):
        """JSON değişkeni ekler"""
        if table_name not in self.tables:
            self._add_json_table(table_name)
        
        self.tables[table_name]['variables'][var_name] = {
            'value': var_value,
            'lastModified': datetime.now().isoformat()
        }
    
    def _edit_var(self, table_name: str, var_name: str, new_value: Any):
        """Değişkeni düzenler"""
        if table_name in self.tables and var_name in self.tables[table_name].get('variables', {}):
            self.tables[table_name]['variables'][var_name]['value'] = new_value
            self.tables[table_name]['variables'][var_name]['lastModified'] = datetime.now().isoformat()
    
    def _remove_var(self, table_name: str, var_name: str):
        """Değişkeni siler"""
        if table_name in self.tables and var_name in self.tables[table_name].get('variables', {}):
            del self.tables[table_name]['variables'][var_name]
    
    # === DATABASE.7945d'DEN ÇEVRİLEN FONKSİYONLAR ===

if __name__ == "__main__":
    # Test
    db = Database7945()
    db.file("./test.7945db")
    print("✅ 7945db Python modülü hazır!")
