import unittest
import time
import sqlite3
from unittest.mock import patch
from storage.adapters.sqlite_adapter import SQLiteAdapter
from security.rbac_engine import RBACEngine

class TestResultsPersistence(unittest.TestCase):
    """Test results persistence functionality including performance metrics."""
    
    def setUp(self):
        """Set up test database and adapter."""
        self.db_path = ":memory:"
        self.encryption_key = "test_key_12345678901234567890123456789012"
        self.adapter = SQLiteAdapter(self.db_path, self.encryption_key)
        
        # Setup mock RBAC
        self.rbac = RBACEngine()
        self.rbac.add_permission("test_user", "storage", "create")
        self.rbac.add_permission("test_user", "storage", "read")
        self.rbac.add_permission("test_user", "storage", "update")
        self.rbac.add_permission("test_user", "storage", "delete")
        self.adapter.rbac = self.rbac
        
    def test_performance_metrics_table_exists(self):
        """Verify performance_metrics table was created."""
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.execute(
                "SELECT name FROM sqlite_master WHERE type='table' AND name='performance_metrics'")
            self.assertIsNotNone(cursor.fetchone())
            
    def test_operation_timing_metrics(self):
        """Verify operations record performance metrics."""
        # Test create operation
        start = time.time()
        self.adapter.create("test_key", "test_value", "test_user")
        create_time = (time.time() - start) * 1000
        
        # Test read operation
        start = time.time()
        self.adapter.read("test_key", "test_user")
        read_time = (time.time() - start) * 1000
        
        # Verify metrics were recorded
        with sqlite3.connect(self.db_path) as conn:
            cursor = conn.execute(
                "SELECT operation, execution_time_ms FROM performance_metrics ORDER BY timestamp")
            metrics = cursor.fetchall()
            
            self.assertEqual(len(metrics), 2)
            self.assertEqual(metrics[0][0], "create")
            self.assertGreaterEqual(metrics[0][1], 0)
            self.assertEqual(metrics[1][0], "read")
            self.assertGreaterEqual(metrics[1][1], 0)
            
    def test_response_time_benchmark(self):
        """Verify operations meet ≤800ms response time requirement."""
        # Warm up
        for _ in range(5):
            self.adapter.create("warm_key", "warm_value", "test_user")
            self.adapter.read("warm_key", "test_user")
        
        # Benchmark create
        start = time.time()
        self.adapter.create("bench_key", "bench_value", "test_user")
        create_time = (time.time() - start) * 1000
        self.assertLessEqual(create_time, 800)
        
        # Benchmark read
        start = time.time()
        self.adapter.read("bench_key", "test_user")
        read_time = (time.time() - start) * 1000
        self.assertLessEqual(read_time, 800)
        
        # Benchmark update
        start = time.time()
        self.adapter.update("bench_key", "new_value", "test_user")
        update_time = (time.time() - start) * 1000
        self.assertLessEqual(update_time, 800)
        
        # Benchmark delete
        start = time.time()
        self.adapter.delete("bench_key", "test_user")
        delete_time = (time.time() - start) * 1000
        self.assertLessEqual(delete_time, 800)

    def test_encryption_integration(self):
        """Verify encrypted values are stored in performance metrics."""
        self.adapter.create("enc_key", "secret_value", "test_user")
        
        with sqlite3.connect(self.db_path) as conn:
            # Verify storage table has encrypted value
            cursor = conn.execute(
                "SELECT encrypted_value FROM storage WHERE key_hash = ?",
                (self.adapter._hash_key("enc_key"),))
            encrypted = cursor.fetchone()[0]
            self.assertNotEqual(encrypted, b"secret_value")
            
    def test_rbac_enforcement(self):
        """Verify RBAC is enforced for performance metrics access."""
        # User without permissions should be denied
        with patch.object(self.rbac, 'validate_permission', return_value=False):
            result = self.adapter.create("rbac_key", "rbac_value", "bad_user")
            self.assertFalse(result)
            
            result = self.adapter.read("rbac_key", "bad_user")
            self.assertIsNone(result)

if __name__ == "__main__":
    unittest.main()