<?php
// Arquivo: includes/DNSDatabase.php
// Banco de dados exclusivo para gestão de DNSs

class DNSDatabase {
    private static $instance = null;
    private $db;
    private $db_path;
    
    private function __construct() {
        // Usar caminho ABSOLUTO para garantir
        $this->db_path = dirname(__DIR__) . '/a/dns_manager.db';
        $this->connect();
        $this->createTables();
    }
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new DNSDatabase();
        }
        return self::$instance;
    }
    
    private function connect() {
        try {
            $this->db = new SQLite3($this->db_path);
            $this->db->busyTimeout(10000);
            $this->db->exec('PRAGMA journal_mode = WAL');
            $this->db->exec('PRAGMA synchronous = NORMAL');
            $this->db->exec('PRAGMA cache_size = 10000');
        } catch (Exception $e) {
            die("Erro ao conectar ao banco de DNS: " . $e->getMessage());
        }
    }
    
    private function createTables() {
        // Tabela principal de DNSs
        $this->db->exec('CREATE TABLE IF NOT EXISTS dns_list (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nome TEXT NOT NULL,
            dns TEXT NOT NULL,
            owner_type TEXT NOT NULL,
            owner_name TEXT NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )');
        
        // Índices para melhor performance
        $this->db->exec('CREATE INDEX IF NOT EXISTS idx_owner ON dns_list(owner_type, owner_name)');
        $this->db->exec('CREATE INDEX IF NOT EXISTS idx_dns ON dns_list(dns)');
        
        // Tabela de logs de uso
        $this->db->exec('CREATE TABLE IF NOT EXISTS dns_usage_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            dns_id INTEGER,
            used_by TEXT,
            used_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            FOREIGN KEY (dns_id) REFERENCES dns_list(id)
        )');
    }
    
    public function create($nome, $dns, $owner_type, $owner_name) {
        $nome = trim($nome);
        $dns = trim($dns);
        $owner_type = trim($owner_type);
        $owner_name = trim($owner_name);
        
        if (empty($nome) || empty($dns) || empty($owner_type) || empty($owner_name)) {
            return false;
        }
        
        try {
            $stmt = $this->db->prepare("INSERT INTO dns_list (nome, dns, owner_type, owner_name) 
                                        VALUES (:nome, :dns, :owner_type, :owner_name)");
            $stmt->bindValue(':nome', $nome, SQLITE3_TEXT);
            $stmt->bindValue(':dns', $dns, SQLITE3_TEXT);
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            return $result !== false;
        } catch (Exception $e) {
            error_log("Erro ao criar DNS: " . $e->getMessage());
            return false;
        }
    }
    
    public function update($id, $nome, $dns, $owner_type, $owner_name) {
        $id = intval($id);
        $nome = trim($nome);
        $dns = trim($dns);
        $owner_type = trim($owner_type);
        $owner_name = trim($owner_name);
        
        try {
            $stmt = $this->db->prepare("UPDATE dns_list 
                                        SET nome = :nome, dns = :dns, updated_at = CURRENT_TIMESTAMP 
                                        WHERE id = :id AND owner_type = :owner_type AND owner_name = :owner_name");
            $stmt->bindValue(':nome', $nome, SQLITE3_TEXT);
            $stmt->bindValue(':dns', $dns, SQLITE3_TEXT);
            $stmt->bindValue(':id', $id, SQLITE3_INTEGER);
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            return $result !== false;
        } catch (Exception $e) {
            error_log("Erro ao atualizar DNS: " . $e->getMessage());
            return false;
        }
    }
    
    public function delete($id, $owner_type, $owner_name) {
        $id = intval($id);
        
        try {
            $stmt = $this->db->prepare("DELETE FROM dns_list WHERE id = :id AND owner_type = :owner_type AND owner_name = :owner_name");
            $stmt->bindValue(':id', $id, SQLITE3_INTEGER);
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            return $result !== false;
        } catch (Exception $e) {
            error_log("Erro ao deletar DNS: " . $e->getMessage());
            return false;
        }
    }
    
    public function getById($id, $owner_type, $owner_name) {
        $id = intval($id);
        
        try {
            $stmt = $this->db->prepare("SELECT * FROM dns_list WHERE id = :id AND owner_type = :owner_type AND owner_name = :owner_name");
            $stmt->bindValue(':id', $id, SQLITE3_INTEGER);
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            return $result->fetchArray(SQLITE3_ASSOC);
        } catch (Exception $e) {
            error_log("Erro ao buscar DNS: " . $e->getMessage());
            return null;
        }
    }
    
    public function getAll($owner_type, $owner_name) {
        $owner_type = trim($owner_type);
        $owner_name = trim($owner_name);
        
        try {
            $stmt = $this->db->prepare("SELECT * FROM dns_list WHERE owner_type = :owner_type AND owner_name = :owner_name ORDER BY id DESC");
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            return $stmt->execute();
        } catch (Exception $e) {
            error_log("Erro ao listar DNS: " . $e->getMessage());
            return null;
        }
    }
    
    public function getCount($owner_type, $owner_name) {
        $owner_type = trim($owner_type);
        $owner_name = trim($owner_name);
        
        try {
            $stmt = $this->db->prepare("SELECT COUNT(*) as total FROM dns_list WHERE owner_type = :owner_type AND owner_name = :owner_name");
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            $row = $result->fetchArray(SQLITE3_ASSOC);
            return $row['total'];
        } catch (Exception $e) {
            error_log("Erro ao contar DNS: " . $e->getMessage());
            return 0;
        }
    }
    
    public function logUsage($dns_id, $used_by) {
        try {
            $stmt = $this->db->prepare("INSERT INTO dns_usage_log (dns_id, used_by) VALUES (:dns_id, :used_by)");
            $stmt->bindValue(':dns_id', $dns_id, SQLITE3_INTEGER);
            $stmt->bindValue(':used_by', $used_by, SQLITE3_TEXT);
            return $stmt->execute() !== false;
        } catch (Exception $e) {
            error_log("Erro ao logar uso DNS: " . $e->getMessage());
            return false;
        }
    }
    
    public function getByDns($dns, $owner_type, $owner_name) {
        $dns = trim($dns);
        
        try {
            $stmt = $this->db->prepare("SELECT * FROM dns_list WHERE dns = :dns AND owner_type = :owner_type AND owner_name = :owner_name");
            $stmt->bindValue(':dns', $dns, SQLITE3_TEXT);
            $stmt->bindValue(':owner_type', $owner_type, SQLITE3_TEXT);
            $stmt->bindValue(':owner_name', $owner_name, SQLITE3_TEXT);
            $result = $stmt->execute();
            return $result->fetchArray(SQLITE3_ASSOC);
        } catch (Exception $e) {
            error_log("Erro ao buscar DNS por URL: " . $e->getMessage());
            return null;
        }
    }
    
    public function getAllDNS() {
        try {
            $result = $this->db->query("SELECT * FROM dns_list ORDER BY owner_type, owner_name, id DESC");
            return $result;
        } catch (Exception $e) {
            error_log("Erro ao listar todas DNS: " . $e->getMessage());
            return null;
        }
    }
    
    public function close() {
        if ($this->db) {
            $this->db->close();
        }
    }
    
    public function __destruct() {
        $this->close();
    }
    
    private function __clone() {}
    public function __wakeup() {}
}
?>