-- ================================================================================================
-- Compliance Views Test Suite (Migration 004)
-- PostgreSQL 16.10 + TimescaleDB 2.22.1
-- Tests SOX, MiFID II, and regulatory compliance views
-- ================================================================================================

BEGIN;

-- ================================================================================================
-- TEST 1: Compliance Views Existence
-- Verify all required compliance views are created
-- ================================================================================================
DO $$
DECLARE
    v_required_views TEXT[] := ARRAY[
        'audit_trail_complete',
        'sox_user_access_report',
        'sox_configuration_changes',
        'mifid_transaction_reporting',
        'mifid_best_execution_analysis',
        'compliance_dashboard',
        'risk_breach_summary',
        'regulatory_audit_log'
    ];
    v_view TEXT;
    v_missing_views TEXT[] := ARRAY[]::TEXT[];
    v_found_count INTEGER := 0;
BEGIN
    FOREACH v_view IN ARRAY v_required_views
    LOOP
        IF EXISTS (
            SELECT 1 FROM information_schema.views
            WHERE table_schema = 'public'
              AND table_name = v_view
        ) THEN
            v_found_count := v_found_count + 1;
        ELSE
            v_missing_views := array_append(v_missing_views, v_view);
        END IF;
    END LOOP;

    IF array_length(v_missing_views, 1) IS NULL THEN
        RAISE NOTICE 'TEST 1 PASS: All % compliance views exist', array_length(v_required_views, 1);
    ELSE
        RAISE WARNING 'TEST 1 WARNING: Missing views (% of %): %', 
            array_length(v_missing_views, 1),
            array_length(v_required_views, 1),
            array_to_string(v_missing_views, ', ');
    END IF;
END $$;

-- ================================================================================================
-- TEST 2: Audit Trail Completeness
-- Verify audit_trail_complete view provides comprehensive audit data
-- ================================================================================================
DO $$
DECLARE
    v_column_count INTEGER;
    v_required_columns TEXT[] := ARRAY[
        'event_id',
        'correlation_id',
        'event_timestamp',
        'event_type',
        'user_id',
        'component',
        'event_data',
        'severity'
    ];
    v_col TEXT;
    v_missing_columns TEXT[] := ARRAY[]::TEXT[];
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'audit_trail_complete') THEN
        RAISE NOTICE 'TEST 2 INFO: Skipping - audit_trail_complete view not found';
        RETURN;
    END IF;

    -- Check required columns
    FOREACH v_col IN ARRAY v_required_columns
    LOOP
        IF NOT EXISTS (
            SELECT 1 FROM information_schema.columns
            WHERE table_name = 'audit_trail_complete'
              AND column_name = v_col
        ) THEN
            v_missing_columns := array_append(v_missing_columns, v_col);
        END IF;
    END LOOP;

    IF array_length(v_missing_columns, 1) IS NULL THEN
        RAISE NOTICE 'TEST 2 PASS: audit_trail_complete has all required columns';
    ELSE
        RAISE WARNING 'TEST 2 WARNING: Missing columns in audit_trail_complete: %', 
            array_to_string(v_missing_columns, ', ');
    END IF;
END $$;

-- ================================================================================================
-- TEST 3: SOX User Access Report
-- Verify SOX compliance view tracks user access properly
-- ================================================================================================
DO $$
DECLARE
    v_test_user_id UUID := uuid_generate_v4();
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
    v_access_count INTEGER;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'sox_user_access_report') THEN
        RAISE NOTICE 'TEST 3 INFO: Skipping - sox_user_access_report view not found';
        RETURN;
    END IF;

    -- Insert test audit events
    INSERT INTO audit_events (
        correlation_id, event_timestamp, event_type, severity, component,
        user_id, event_data, event_hash, node_id, process_id
    ) VALUES
    (uuid_generate_v4(), v_current_ns, 'authentication_success', 'info', 'authentication',
     v_test_user_id::text, '{"action": "login", "ip": "192.168.1.100"}'::jsonb, 
     encode(sha256('sox1'::bytea), 'hex'), 'node-01', 12345),
    (uuid_generate_v4(), v_current_ns + 1000000, 'permission_granted', 'notice', 'authorization',
     v_test_user_id::text, '{"permission": "read:trades"}'::jsonb, 
     encode(sha256('sox2'::bytea), 'hex'), 'node-01', 12345);

    -- Query view
    EXECUTE format('SELECT COUNT(*) FROM sox_user_access_report WHERE user_id = %L', v_test_user_id::text)
    INTO v_access_count;

    IF v_access_count >= 0 THEN
        RAISE NOTICE 'TEST 3 PASS: SOX user access report queryable (found % matching records)', v_access_count;
    ELSE
        RAISE EXCEPTION 'TEST 3 FAIL: SOX user access report query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 4: SOX Configuration Changes
-- Verify configuration change tracking for SOX compliance
-- ================================================================================================
DO $$
DECLARE
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
    v_config_count INTEGER;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'sox_configuration_changes') THEN
        RAISE NOTICE 'TEST 4 INFO: Skipping - sox_configuration_changes view not found';
        RETURN;
    END IF;

    -- Insert test configuration change events
    INSERT INTO audit_events (
        correlation_id, event_timestamp, event_type, severity, component,
        user_id, event_data, event_hash, node_id, process_id
    ) VALUES
    (uuid_generate_v4(), v_current_ns, 'configuration_updated', 'notice', 'configuration',
     'admin_user', '{"key": "risk_limit", "old": "100000", "new": "150000"}'::jsonb,
     encode(sha256('config1'::bytea), 'hex'), 'node-01', 12345);

    -- Query view
    EXECUTE 'SELECT COUNT(*) FROM sox_configuration_changes WHERE event_timestamp >= $1'
    INTO v_config_count
    USING v_current_ns;

    IF v_config_count >= 0 THEN
        RAISE NOTICE 'TEST 4 PASS: SOX configuration changes tracking operational (found % records)', v_config_count;
    ELSE
        RAISE EXCEPTION 'TEST 4 FAIL: SOX configuration changes query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 5: MiFID Transaction Reporting
-- Verify MiFID II transaction reporting compliance
-- ================================================================================================
DO $$
DECLARE
    v_order_id UUID := uuid_generate_v4();
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
    v_transaction_count INTEGER;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'mifid_transaction_reporting') THEN
        RAISE NOTICE 'TEST 5 INFO: Skipping - mifid_transaction_reporting view not found';
        RETURN;
    END IF;

    -- Insert test order
    INSERT INTO orders (
        id, symbol, side, order_type, time_in_force,
        quantity, limit_price, account_id, venue
    ) VALUES (
        v_order_id, 'AAPL', 'buy', 'limit', 'day',
        100, 15000, 'ACC001', 'NASDAQ'
    );

    -- Insert execution
    INSERT INTO executions (
        order_id, symbol, side, quantity, price,
        venue, execution_timestamp, execution_type
    ) VALUES (
        v_order_id, 'AAPL', 'buy', 100, 15050,
        'NASDAQ', v_current_ns, 'fill'
    );

    -- Query view
    EXECUTE format('SELECT COUNT(*) FROM mifid_transaction_reporting WHERE order_id = %L', v_order_id)
    INTO v_transaction_count;

    IF v_transaction_count >= 0 THEN
        RAISE NOTICE 'TEST 5 PASS: MiFID transaction reporting functional (found % records)', v_transaction_count;
    ELSE
        RAISE EXCEPTION 'TEST 5 FAIL: MiFID transaction reporting query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 6: Best Execution Analysis
-- Verify MiFID II best execution analysis
-- ================================================================================================
DO $$
DECLARE
    v_execution_count INTEGER;
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'mifid_best_execution_analysis') THEN
        RAISE NOTICE 'TEST 6 INFO: Skipping - mifid_best_execution_analysis view not found';
        RETURN;
    END IF;

    -- Insert test executions at different venues
    INSERT INTO executions (
        order_id, symbol, side, quantity, price,
        venue, execution_timestamp, execution_type
    ) VALUES
    (uuid_generate_v4(), 'MSFT', 'buy', 50, 40000, 'NYSE', v_current_ns, 'fill'),
    (uuid_generate_v4(), 'MSFT', 'buy', 50, 40010, 'NASDAQ', v_current_ns + 100000, 'fill'),
    (uuid_generate_v4(), 'MSFT', 'buy', 50, 40005, 'ARCA', v_current_ns + 200000, 'fill');

    -- Query view
    EXECUTE 'SELECT COUNT(*) FROM mifid_best_execution_analysis WHERE symbol = $1'
    INTO v_execution_count
    USING 'MSFT';

    IF v_execution_count >= 0 THEN
        RAISE NOTICE 'TEST 6 PASS: Best execution analysis operational (found % records)', v_execution_count;
    ELSE
        RAISE EXCEPTION 'TEST 6 FAIL: Best execution analysis query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 7: Compliance Dashboard View
-- Verify compliance dashboard aggregates all compliance data
-- ================================================================================================
DO $$
DECLARE
    v_dashboard_count INTEGER;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'compliance_dashboard') THEN
        RAISE NOTICE 'TEST 7 INFO: Skipping - compliance_dashboard view not found';
        RETURN;
    END IF;

    -- Query view
    EXECUTE 'SELECT COUNT(*) FROM compliance_dashboard'
    INTO v_dashboard_count;

    IF v_dashboard_count >= 0 THEN
        RAISE NOTICE 'TEST 7 PASS: Compliance dashboard view queryable (% records)', v_dashboard_count;
    ELSE
        RAISE EXCEPTION 'TEST 7 FAIL: Compliance dashboard query failed';
    END IF;

    -- Check if view has required aggregations
    IF EXISTS (
        SELECT 1 FROM information_schema.columns
        WHERE table_name = 'compliance_dashboard'
          AND column_name IN ('total_transactions', 'risk_breaches', 'audit_events')
    ) THEN
        RAISE NOTICE 'TEST 7 INFO: Dashboard includes aggregated compliance metrics';
    END IF;
END $$;

-- ================================================================================================
-- TEST 8: Risk Breach Summary
-- Verify risk breach aggregation for compliance reporting
-- ================================================================================================
DO $$
DECLARE
    v_breach_count INTEGER;
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'risk_breach_summary') THEN
        RAISE NOTICE 'TEST 8 INFO: Skipping - risk_breach_summary view not found';
        RETURN;
    END IF;

    -- Insert test risk events
    INSERT INTO risk_events (
        correlation_id, event_timestamp, detected_timestamp,
        event_type, severity, symbol, account_id,
        event_data, event_hash, node_id, process_id
    ) VALUES
    (uuid_generate_v4(), v_current_ns, v_current_ns, 'var_breach', 'high', 
     'AAPL', 'ACC001', '{"breach_amount": 25000}'::jsonb,
     encode(sha256('breach1'::bytea), 'hex'), 'node-01', 12345),
    (uuid_generate_v4(), v_current_ns + 1000000, v_current_ns + 1000000, 'position_limit_breach', 'critical',
     'TSLA', 'ACC001', '{"breach_amount": 50000}'::jsonb,
     encode(sha256('breach2'::bytea), 'hex'), 'node-01', 12345);

    -- Query view
    EXECUTE 'SELECT COUNT(*) FROM risk_breach_summary WHERE severity IN ($1, $2)'
    INTO v_breach_count
    USING 'high', 'critical';

    IF v_breach_count >= 0 THEN
        RAISE NOTICE 'TEST 8 PASS: Risk breach summary operational (found % breaches)', v_breach_count;
    ELSE
        RAISE EXCEPTION 'TEST 8 FAIL: Risk breach summary query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 9: Regulatory Audit Log
-- Verify comprehensive regulatory audit logging
-- ================================================================================================
DO $$
DECLARE
    v_audit_count INTEGER;
    v_current_ns BIGINT := EXTRACT(EPOCH FROM NOW())::BIGINT * 1000000000;
BEGIN
    -- Check if view exists
    IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = 'regulatory_audit_log') THEN
        RAISE NOTICE 'TEST 9 INFO: Skipping - regulatory_audit_log view not found';
        RETURN;
    END IF;

    -- Insert various audit events
    INSERT INTO audit_events (
        correlation_id, event_timestamp, event_type, severity, component,
        user_id, event_data, event_hash, node_id, process_id
    ) VALUES
    (uuid_generate_v4(), v_current_ns, 'compliance_validation_completed', 'info', 'compliance_engine',
     'system', '{"validation": "pre_trade_check", "result": "pass"}'::jsonb,
     encode(sha256('reg1'::bytea), 'hex'), 'node-01', 12345),
    (uuid_generate_v4(), v_current_ns + 1000000, 'regulatory_report_generated', 'notice', 'reporting',
     'system', '{"report_type": "daily_position"}'::jsonb,
     encode(sha256('reg2'::bytea), 'hex'), 'node-01', 12345);

    -- Query view
    EXECUTE 'SELECT COUNT(*) FROM regulatory_audit_log WHERE event_timestamp >= $1'
    INTO v_audit_count
    USING v_current_ns;

    IF v_audit_count >= 0 THEN
        RAISE NOTICE 'TEST 9 PASS: Regulatory audit log operational (found % events)', v_audit_count;
    ELSE
        RAISE EXCEPTION 'TEST 9 FAIL: Regulatory audit log query failed';
    END IF;
END $$;

-- ================================================================================================
-- TEST 10: Compliance View Performance
-- Verify compliance views have acceptable query performance
-- ================================================================================================
DO $$
DECLARE
    v_start_time TIMESTAMP;
    v_end_time TIMESTAMP;
    v_duration INTERVAL;
    v_view_name TEXT;
    v_views TEXT[] := ARRAY['audit_trail_complete', 'sox_user_access_report', 'mifid_transaction_reporting'];
BEGIN
    FOREACH v_view_name IN ARRAY v_views
    LOOP
        -- Check if view exists
        IF NOT EXISTS (SELECT 1 FROM information_schema.views WHERE table_name = v_view_name) THEN
            CONTINUE;
        END IF;

        v_start_time := clock_timestamp();
        
        -- Query view with LIMIT to test index usage
        EXECUTE format('SELECT * FROM %I LIMIT 100', v_view_name);
        
        v_end_time := clock_timestamp();
        v_duration := v_end_time - v_start_time;

        IF v_duration < INTERVAL '1 second' THEN
            RAISE NOTICE 'TEST 10 INFO: View % query time: %', v_view_name, v_duration;
        ELSE
            RAISE WARNING 'TEST 10 WARNING: View % slow query (% > 1s)', v_view_name, v_duration;
        END IF;
    END LOOP;

    RAISE NOTICE 'TEST 10 PASS: Compliance view performance tests completed';
END $$;

-- ================================================================================================
-- Cleanup: Rollback all test data
-- ================================================================================================
ROLLBACK;

-- Test Summary
SELECT 'Compliance Views Test Suite Completed - Review NOTICE/WARNING messages above' AS test_summary;
