-- ============================================================
-- CLEANUP & DISABLE AUDIT - Oracle XE 11g/12c/18c/21c
-- ============================================================
-- Compatibil cu: Oracle 11g XE, 12c, 18c XE, 21c XE
-- Compatibil cu: non-CDB si CDB/PDB
-- Scop: Curata audit trail din SYSAUX + dezactiveaza auditurile
--        + curata advisor objects + scheduler log
--        + resize UNDO si SYSAUX datafiles
-- Rulat ca: SYS AS SYSDBA
--   - non-CDB: sqlplus / as sysdba
--   - CDB/PDB: conectat la PDB (ALTER SESSION SET CONTAINER = XEPDB1)
-- ============================================================
--
-- IMPORTANT: Pe Oracle XE, audit-urile active umfla SYSAUX/AUDSYS
-- pana la limita de 12 GB si blocheaza baza cu ORA-12954.
-- Acest script:
--   1. Detecteaza versiunea Oracle si tipul bazei (CDB/non-CDB)
--   2. Dezactiveaza TOATE audit policies (unified + traditional)
--   3. Curata audit trail-urile existente
--   4. Configureaza auto-purge pentru siguranta
--   5. Dezactiveaza auto tasks care umfla SYSAUX
--   6. Curata SQL Advisor objects (WRI$_ADV_*) - pot ocupa GB
--   7. Curata scheduler event log
--   8. Resize UNDO si SYSAUX datafiles
--   9. Verifica rezultatul
-- ============================================================

SET SERVEROUTPUT ON SIZE UNLIMITED
SET FEEDBACK OFF
SET VERIFY OFF

SPOOL cleanup_audit.log

DECLARE
    v_version     NUMBER;
    v_full_ver    VARCHAR2(100);
    v_is_cdb      VARCHAR2(3) := 'NO';
    v_con_name    VARCHAR2(128) := 'NON-CDB';
    v_count       NUMBER;
    v_aud_size_mb NUMBER := 0;
    v_sysaux_mb   NUMBER := 0;
    v_undo_file   VARCHAR2(512);
    v_undo_mb     NUMBER;
    v_sysaux_file VARCHAR2(512);
    v_sysaux_df   NUMBER;
    v_hwm         NUMBER;

    -- Helper: executa SQL si ignora erori
    PROCEDURE exec_ignore(p_sql VARCHAR2) IS
    BEGIN
        EXECUTE IMMEDIATE p_sql;
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] ' || SUBSTR(SQLERRM, 1, 200));
    END;

    -- Helper: executa SQL cu output
    PROCEDURE exec_log(p_sql VARCHAR2, p_desc VARCHAR2) IS
    BEGIN
        EXECUTE IMMEDIATE p_sql;
        DBMS_OUTPUT.PUT_LINE('  [OK] ' || p_desc);
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] ' || p_desc || ' - ' || SUBSTR(SQLERRM, 1, 150));
    END;

BEGIN
    -- =========================================================
    -- DETECTIE VERSIUNE SI TIP BAZA
    -- =========================================================
    -- version_full exista doar pe 18c+, version exista pe toate
    BEGIN
        EXECUTE IMMEDIATE 'SELECT version_full FROM v$instance' INTO v_full_ver;
    EXCEPTION WHEN OTHERS THEN
        SELECT version INTO v_full_ver FROM v$instance;
    END;

    v_version := TO_NUMBER(SUBSTR(v_full_ver, 1, INSTR(v_full_ver, '.') - 1));

    DBMS_OUTPUT.PUT_LINE('============================================================');
    DBMS_OUTPUT.PUT_LINE(' CLEANUP AUDIT - Oracle ' || v_full_ver);
    DBMS_OUTPUT.PUT_LINE('============================================================');

    -- Detectie CDB (12c+)
    IF v_version >= 12 THEN
        BEGIN
            EXECUTE IMMEDIATE 'SELECT CDB FROM V$DATABASE' INTO v_is_cdb;
        EXCEPTION WHEN OTHERS THEN
            v_is_cdb := 'NO';
        END;

        IF v_is_cdb = 'YES' THEN
            EXECUTE IMMEDIATE 'SELECT SYS_CONTEXT(''USERENV'', ''CON_NAME'') FROM DUAL' INTO v_con_name;
        END IF;
    END IF;

    DBMS_OUTPUT.PUT_LINE(' Versiune: ' || v_version || ' | CDB: ' || v_is_cdb || ' | Container: ' || v_con_name);

    -- Warning daca suntem pe CDB$ROOT
    IF v_con_name = 'CDB$ROOT' AND v_is_cdb = 'YES' THEN
        DBMS_OUTPUT.PUT_LINE(' ');
        DBMS_OUTPUT.PUT_LINE(' !!! ATENTIE: Esti conectat la CDB$ROOT !!!');
        DBMS_OUTPUT.PUT_LINE(' !!! Ruleaza scriptul si pe fiecare PDB: !!!');
        DBMS_OUTPUT.PUT_LINE(' !!!   ALTER SESSION SET CONTAINER = XEPDB1; !!!');
        DBMS_OUTPUT.PUT_LINE(' !!!   @cleanup_audit.sql                    !!!');
        DBMS_OUTPUT.PUT_LINE(' ');
    END IF;

    -- Spatiu SYSAUX inainte
    SELECT ROUND(SUM(bytes)/1024/1024)
    INTO v_sysaux_mb
    FROM dba_segments
    WHERE tablespace_name = 'SYSAUX';

    DBMS_OUTPUT.PUT_LINE(' SYSAUX segmente inainte: ' || v_sysaux_mb || ' MB');
    DBMS_OUTPUT.PUT_LINE('------------------------------------------------------------');

    -- =========================================================
    -- PASUL 1: DEZACTIVARE UNIFIED AUDIT POLICIES (12c+)
    -- =========================================================
    IF v_version >= 12 THEN
        DBMS_OUTPUT.PUT_LINE(' ');
        DBMS_OUTPUT.PUT_LINE('[PASUL 1] Dezactivare unified audit policies...');

        -- Dezactiveaza toate politicile active
        FOR rec IN (
            SELECT DISTINCT policy_name
            FROM audit_unified_enabled_policies
        ) LOOP
            exec_log('NOAUDIT POLICY ' || rec.policy_name, 'NOAUDIT POLICY ' || rec.policy_name);
        END LOOP;

        -- Verifica
        SELECT COUNT(*) INTO v_count FROM audit_unified_enabled_policies;
        IF v_count = 0 THEN
            DBMS_OUTPUT.PUT_LINE('  [OK] Toate politicile unified audit dezactivate');
        ELSE
            DBMS_OUTPUT.PUT_LINE('  [WARN] Inca ' || v_count || ' politici active!');
        END IF;
    ELSE
        DBMS_OUTPUT.PUT_LINE(' ');
        DBMS_OUTPUT.PUT_LINE('[PASUL 1] Oracle ' || v_version || ' - nu are unified audit, skip');
    END IF;

    -- =========================================================
    -- PASUL 2: DEZACTIVARE TRADITIONAL AUDIT (11g-21c)
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 2] Dezactivare traditional audit...');

    exec_log('NOAUDIT ALL', 'NOAUDIT ALL');
    exec_log('NOAUDIT ALL PRIVILEGES', 'NOAUDIT ALL PRIVILEGES');

    -- Dezactiveaza audituri per-user
    FOR rec IN (
        SELECT DISTINCT user_name
        FROM dba_stmt_audit_opts
        WHERE user_name IS NOT NULL
    ) LOOP
        exec_log('NOAUDIT ALL BY ' || rec.user_name, 'NOAUDIT ALL BY ' || rec.user_name);
    END LOOP;

    -- Dezactiveaza audituri pe obiecte
    FOR rec IN (
        SELECT owner, object_name, object_type
        FROM dba_obj_audit_opts
        WHERE alt != '-/-' OR aud != '-/-' OR com != '-/-'
              OR del != '-/-' OR gra != '-/-' OR ind != '-/-'
              OR ins != '-/-' OR loc != '-/-' OR ren != '-/-'
              OR sel != '-/-' OR upd != '-/-' OR exe != '-/-'
    ) LOOP
        BEGIN
            EXECUTE IMMEDIATE 'NOAUDIT ALL ON ' || rec.owner || '.' || rec.object_name;
            DBMS_OUTPUT.PUT_LINE('  [OK] NOAUDIT ALL ON ' || rec.owner || '.' || rec.object_name);
        EXCEPTION WHEN OTHERS THEN NULL;
        END;
    END LOOP;

    -- =========================================================
    -- PASUL 3: CLEANUP UNIFIED AUDIT TRAIL (12c+)
    -- =========================================================
    IF v_version >= 12 THEN
        DBMS_OUTPUT.PUT_LINE(' ');
        DBMS_OUTPUT.PUT_LINE('[PASUL 3] Cleanup unified audit trail...');

        -- Dimensiune audit trail
        BEGIN
            EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM unified_audit_trail' INTO v_count;
            DBMS_OUTPUT.PUT_LINE('  Inregistrari in unified_audit_trail: ' || v_count);
        EXCEPTION WHEN OTHERS THEN
            v_count := 0;
        END;

        IF v_count > 0 THEN
            -- Seteaza timestamp de arhivare in trecut (permite stergerea tuturor)
            BEGIN
                DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
                    audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
                    last_archive_time => SYSTIMESTAMP + INTERVAL '1' DAY
                );
                DBMS_OUTPUT.PUT_LINE('  [OK] Archive timestamp setat');
            EXCEPTION WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('  [SKIP] Archive timestamp: ' || SUBSTR(SQLERRM, 1, 150));
            END;

            -- Curata trail-ul
            BEGIN
                DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
                    audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_UNIFIED,
                    use_last_arch_timestamp => TRUE
                );
                DBMS_OUTPUT.PUT_LINE('  [OK] Unified audit trail curatat');
            EXCEPTION WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('  [FAIL] Cleanup unified: ' || SUBSTR(SQLERRM, 1, 150));
                DBMS_OUTPUT.PUT_LINE('  [INFO] Daca ORA-12954, curata mai intai SQL Tuning Sets (vezi Pasul 5)');
                DBMS_OUTPUT.PUT_LINE('  [INFO] Apoi reruleaza acest script');
            END;

            -- Verifica cate au ramas
            BEGIN
                EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM unified_audit_trail' INTO v_count;
                DBMS_OUTPUT.PUT_LINE('  Inregistrari ramase: ' || v_count);
            EXCEPTION WHEN OTHERS THEN NULL;
            END;
        ELSE
            DBMS_OUTPUT.PUT_LINE('  [OK] Unified audit trail gol, nimic de curatat');
        END IF;
    END IF;

    -- =========================================================
    -- PASUL 4: CLEANUP TRADITIONAL AUDIT TRAIL (AUD$)
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 4] Cleanup traditional audit trail (AUD$)...');

    -- Dimensiune AUD$
    BEGIN
        SELECT COUNT(*) INTO v_count FROM sys.aud$;
        DBMS_OUTPUT.PUT_LINE('  Inregistrari in AUD$: ' || v_count);
    EXCEPTION WHEN OTHERS THEN
        v_count := 0;
        DBMS_OUTPUT.PUT_LINE('  [SKIP] AUD$ nu exista sau nu e accesibil');
    END;

    IF v_count > 0 THEN
        -- Curata via DBMS_AUDIT_MGMT
        BEGIN
            DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(
                audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                last_archive_time => SYSTIMESTAMP + INTERVAL '1' DAY
            );
            DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
                audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                use_last_arch_timestamp => TRUE
            );
            DBMS_OUTPUT.PUT_LINE('  [OK] AUD$ curatat via DBMS_AUDIT_MGMT');
        EXCEPTION WHEN OTHERS THEN
            DBMS_OUTPUT.PUT_LINE('  [SKIP] DBMS_AUDIT_MGMT: ' || SUBSTR(SQLERRM, 1, 150));
            -- Fallback: TRUNCATE direct
            BEGIN
                EXECUTE IMMEDIATE 'TRUNCATE TABLE sys.aud$';
                DBMS_OUTPUT.PUT_LINE('  [OK] AUD$ curatat via TRUNCATE');
            EXCEPTION WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('  [FAIL] TRUNCATE AUD$: ' || SUBSTR(SQLERRM, 1, 150));
            END;
        END;
    END IF;

    -- Curata FGA_LOG$ (Fine-Grained Audit)
    BEGIN
        SELECT COUNT(*) INTO v_count FROM sys.fga_log$;
        IF v_count > 0 THEN
            DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(
                audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD,
                use_last_arch_timestamp => FALSE
            );
            DBMS_OUTPUT.PUT_LINE('  [OK] FGA_LOG$ curatat (' || v_count || ' inregistrari)');
        END IF;
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] FGA_LOG$: ' || SUBSTR(SQLERRM, 1, 150));
    END;

    -- =========================================================
    -- PASUL 5: CLEANUP SQL TUNING SETS (SYSAUX - cel mai mare vinovat)
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 5] Cleanup SQL Tuning Sets din SYSAUX...');

    -- Drop SQL Tuning Sets
    FOR rec IN (SELECT name, owner FROM dba_sqlset) LOOP
        BEGIN
            DBMS_SQLTUNE.DROP_SQLSET(rec.name, rec.owner);
            DBMS_OUTPUT.PUT_LINE('  [OK] Drop SQLSET: ' || rec.owner || '.' || rec.name);
        EXCEPTION WHEN OTHERS THEN NULL;
        END;
    END LOOP;

    -- TRUNCATE tabelele daca DROP nu a eliberat spatiul
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_plan_lines', 'TRUNCATE wri$_sqlset_plan_lines');
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_plans',      'TRUNCATE wri$_sqlset_plans');
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_statistics',  'TRUNCATE wri$_sqlset_statistics');
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_statements',  'TRUNCATE wri$_sqlset_statements');
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_references',  'TRUNCATE wri$_sqlset_references');
    exec_log('TRUNCATE TABLE sys.wri$_sqlset_definitions', 'TRUNCATE wri$_sqlset_definitions');

    -- Cleanup stats + recyclebin
    exec_log('BEGIN DBMS_STATS.PURGE_STATS(SYSDATE - 7); END;', 'Purge stats older than 7 days');
    exec_log('PURGE DBA_RECYCLEBIN', 'Purge recyclebin');

    -- =========================================================
    -- PASUL 5b: CLEANUP SQL ADVISOR OBJECTS (WRI$_ADV_*)
    -- =========================================================
    -- WRI$_ADV_OBJECTS poate acumula milioane de randuri (GB)
    -- Sunt doar recomandari de tuning, nu date de productie
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 5b] Cleanup SQL Advisor objects...');

    -- Truncate in ordinea corecta (foreign keys)
    exec_log('TRUNCATE TABLE sys.wri$_adv_actions',         'TRUNCATE wri$_adv_actions');
    exec_log('TRUNCATE TABLE sys.wri$_adv_findings',        'TRUNCATE wri$_adv_findings');
    exec_log('TRUNCATE TABLE sys.wri$_adv_recommendations', 'TRUNCATE wri$_adv_recommendations');
    exec_log('TRUNCATE TABLE sys.wri$_adv_rationale',       'TRUNCATE wri$_adv_rationale');
    exec_log('TRUNCATE TABLE sys.wri$_adv_journal',         'TRUNCATE wri$_adv_journal');
    exec_log('TRUNCATE TABLE sys.wri$_adv_objects',         'TRUNCATE wri$_adv_objects');

    -- =========================================================
    -- PASUL 5c: CLEANUP SCHEDULER EVENT LOG
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 5c] Cleanup scheduler event log...');

    exec_log('TRUNCATE TABLE sys.scheduler$_event_log', 'TRUNCATE scheduler$_event_log');

    -- =========================================================
    -- PASUL 6: DEZACTIVARE AUTO TASKS
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 6] Dezactivare auto tasks...');

    BEGIN
        DBMS_AUTO_TASK_ADMIN.DISABLE(
            client_name => 'sql tuning advisor',
            operation   => NULL,
            window_name => NULL
        );
        DBMS_OUTPUT.PUT_LINE('  [OK] sql tuning advisor DISABLED');
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] sql tuning advisor: ' || SUBSTR(SQLERRM, 1, 150));
    END;

    BEGIN
        DBMS_AUTO_TASK_ADMIN.DISABLE(
            client_name => 'auto space advisor',
            operation   => NULL,
            window_name => NULL
        );
        DBMS_OUTPUT.PUT_LINE('  [OK] auto space advisor DISABLED');
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] auto space advisor: ' || SUBSTR(SQLERRM, 1, 150));
    END;

    -- =========================================================
    -- PASUL 7: AWR RETENTION + STATS RETENTION
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 7] Configurare AWR retention...');

    -- Incearca 8 zile (min moving window baseline)
    BEGIN
        DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
            retention => 8 * 24 * 60,
            interval  => 60
        );
        DBMS_OUTPUT.PUT_LINE('  [OK] AWR retention = 8 zile, interval = 60 min');
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] AWR: ' || SUBSTR(SQLERRM, 1, 150));
    END;

    BEGIN
        DBMS_STATS.ALTER_STATS_HISTORY_RETENTION(7);
        DBMS_OUTPUT.PUT_LINE('  [OK] Stats history retention = 7 zile');
    EXCEPTION WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('  [SKIP] Stats retention: ' || SUBSTR(SQLERRM, 1, 150));
    END;

    -- =========================================================
    -- PASUL 8: GRANT DBMS_LOCK (necesar pt PACK_UTILS_FILE)
    -- =========================================================
    IF v_version >= 12 THEN
        DBMS_OUTPUT.PUT_LINE(' ');
        DBMS_OUTPUT.PUT_LINE('[PASUL 8] Grant DBMS_LOCK...');
        exec_log('GRANT EXECUTE ON SYS.DBMS_LOCK TO CONTAFIN_ORACLE', 'GRANT DBMS_LOCK TO CONTAFIN_ORACLE');
    END IF;

    -- =========================================================
    -- PASUL 9: RESIZE UNDO DATAFILE
    -- =========================================================
    -- UNDO poate creste foarte mult dupa import-uri bulk
    -- undo_retention=900 (15 min) e suficient pentru XE
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 9] Resize UNDO datafile...');

    exec_log('ALTER SYSTEM SET undo_retention = 900', 'undo_retention = 900');

    BEGIN
        SELECT file_name, ROUND(bytes/1024/1024)
        INTO v_undo_file, v_undo_mb
        FROM dba_data_files
        WHERE tablespace_name = 'UNDOTBS1'
        AND ROWNUM = 1;

        DBMS_OUTPUT.PUT_LINE('  UNDO datafile: ' || v_undo_file || ' (' || v_undo_mb || ' MB)');

        IF v_undo_mb > 2048 THEN
            -- Incearca resize la 2 GB, apoi 4 GB, apoi 6 GB
            BEGIN
                EXECUTE IMMEDIATE 'ALTER DATABASE DATAFILE ''' || v_undo_file || ''' RESIZE 2G';
                DBMS_OUTPUT.PUT_LINE('  [OK] UNDO resize la 2 GB');
            EXCEPTION WHEN OTHERS THEN
                BEGIN
                    EXECUTE IMMEDIATE 'ALTER DATABASE DATAFILE ''' || v_undo_file || ''' RESIZE 4G';
                    DBMS_OUTPUT.PUT_LINE('  [OK] UNDO resize la 4 GB');
                EXCEPTION WHEN OTHERS THEN
                    BEGIN
                        EXECUTE IMMEDIATE 'ALTER DATABASE DATAFILE ''' || v_undo_file || ''' RESIZE 6G';
                        DBMS_OUTPUT.PUT_LINE('  [OK] UNDO resize la 6 GB');
                    EXCEPTION WHEN OTHERS THEN
                        DBMS_OUTPUT.PUT_LINE('  [SKIP] UNDO resize: ' || SUBSTR(SQLERRM, 1, 150));
                    END;
                END;
            END;
        ELSE
            DBMS_OUTPUT.PUT_LINE('  [OK] UNDO deja <= 2 GB, skip resize');
        END IF;
    END;

    -- =========================================================
    -- PASUL 10: RESIZE SYSAUX DATAFILE
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('[PASUL 10] Resize SYSAUX datafile...');

    BEGIN
        SELECT file_name, ROUND(bytes/1024/1024)
        INTO v_sysaux_file, v_sysaux_df
        FROM dba_data_files
        WHERE tablespace_name = 'SYSAUX'
        AND ROWNUM = 1;

        -- Calculeaza high water mark
        SELECT CEIL(MAX(block_id + blocks) * 8192 / 1024 / 1024)
        INTO v_hwm
        FROM dba_extents
        WHERE tablespace_name = 'SYSAUX';

        DBMS_OUTPUT.PUT_LINE('  SYSAUX datafile: ' || v_sysaux_file || ' (' || v_sysaux_df || ' MB)');
        DBMS_OUTPUT.PUT_LINE('  SYSAUX HWM: ' || v_hwm || ' MB');

        -- Resize doar daca putem recupera cel putin 500 MB
        IF v_sysaux_df - v_hwm > 500 THEN
            BEGIN
                EXECUTE IMMEDIATE 'ALTER DATABASE DATAFILE ''' || v_sysaux_file
                    || ''' RESIZE ' || (v_hwm + 100) || 'M';
                DBMS_OUTPUT.PUT_LINE('  [OK] SYSAUX resize la ' || (v_hwm + 100) || ' MB');
            EXCEPTION WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('  [SKIP] SYSAUX resize: ' || SUBSTR(SQLERRM, 1, 150));
                DBMS_OUTPUT.PUT_LINE('  [INFO] HWM prea aproape de dim. curenta, spatiul se va reutiliza');
            END;
        ELSE
            DBMS_OUTPUT.PUT_LINE('  [SKIP] Diferenta < 500 MB, nu merita resize');
            DBMS_OUTPUT.PUT_LINE('  [INFO] Spatiul liber din SYSAUX se va reutiliza automat');
        END IF;
    END;

    -- =========================================================
    -- VERIFICARE FINALA
    -- =========================================================
    DBMS_OUTPUT.PUT_LINE(' ');
    DBMS_OUTPUT.PUT_LINE('============================================================');
    DBMS_OUTPUT.PUT_LINE(' VERIFICARE FINALA');
    DBMS_OUTPUT.PUT_LINE('============================================================');

    -- SYSAUX dupa
    SELECT ROUND(SUM(bytes)/1024/1024)
    INTO v_sysaux_mb
    FROM dba_segments
    WHERE tablespace_name = 'SYSAUX';
    DBMS_OUTPUT.PUT_LINE(' SYSAUX segmente dupa: ' || v_sysaux_mb || ' MB');

    -- Audit policies (12c+)
    IF v_version >= 12 THEN
        SELECT COUNT(*) INTO v_count FROM audit_unified_enabled_policies;
        IF v_count = 0 THEN
            DBMS_OUTPUT.PUT_LINE(' Unified audit policies: NONE (OK)');
        ELSE
            DBMS_OUTPUT.PUT_LINE(' Unified audit policies: ' || v_count || ' ACTIVE (WARN!)');
        END IF;
    END IF;

    -- Traditional audit
    BEGIN
        SELECT COUNT(*) INTO v_count FROM dba_stmt_audit_opts;
        DBMS_OUTPUT.PUT_LINE(' Traditional audit opts: ' || v_count);
    EXCEPTION WHEN OTHERS THEN NULL;
    END;

    -- Auto tasks
    DBMS_OUTPUT.PUT_LINE(' Auto tasks:');
    FOR rec IN (SELECT client_name, status FROM dba_autotask_client) LOOP
        DBMS_OUTPUT.PUT_LINE('   ' || RPAD(rec.client_name, 45) || rec.status);
    END LOOP;

    -- Total alocat
    BEGIN
        SELECT ROUND(SUM(bytes)/1024/1024) INTO v_sysaux_mb FROM dba_data_files;
        DBMS_OUTPUT.PUT_LINE(' Total datafiles: ' || v_sysaux_mb || ' MB / 12288 MB (XE limit)');
    EXCEPTION WHEN OTHERS THEN NULL;
    END;

    DBMS_OUTPUT.PUT_LINE('============================================================');
    DBMS_OUTPUT.PUT_LINE(' CLEANUP COMPLET!');
    DBMS_OUTPUT.PUT_LINE('============================================================');

END;
/

SPOOL OFF
