<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <!-- SNMP Data Collection Configuration Database Schema -->

    <!-- 1. Collection Profiles -->
    <changeSet author="cgorantla" id="36.0.0-snmp-collection-profiles-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="snmp_collection_profiles"/>
            </not>
        </preConditions>

        <createTable tableName="snmp_collection_profiles">
            <column name="id" type="integer">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(256)">
                <constraints nullable="false" unique="true"/>
            </column>
            <column name="rrd_step" type="integer">
                <constraints nullable="false"/>
            </column>
            <column name="rrd_rras" type="text"/>
            <column name="storage_flag" type="varchar(50)" defaultValue="select">
                <constraints nullable="false"/>
            </column>
            <column name="source_names" type="text"/>
            <column name="max_vars_per_pdu" type="integer"/>
            <column name="enabled" type="boolean" defaultValueBoolean="true">
                <constraints nullable="false"/>
            </column>
            <column name="created_time" type="timestamp with time zone" defaultValueComputed="NOW()">
                <constraints nullable="false"/>
            </column>
            <column name="last_modified" type="timestamp with time zone"/>
        </createTable>

        <createSequence sequenceName="snmp_collection_profiles_id_seq" startValue="1" incrementBy="1"/>

        <rollback>
            <dropTable tableName="snmp_collection_profiles"/>
        </rollback>
    </changeSet>

    <!-- 2. DataCollection Sources (vendor-specific definitions) -->
    <changeSet author="cgorantla" id="36.0.0-snmp-collection-sources-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="snmp_collection_sources"/>
            </not>
        </preConditions>

        <createTable tableName="snmp_collection_sources">
            <column name="id" type="integer">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(256)">
                <constraints nullable="false" unique="true"/>
            </column>
            <column name="vendor" type="varchar(128)"/>
            <column name="description" type="text"/>
            <column name="enabled" type="boolean" defaultValueBoolean="true">
                <constraints nullable="false"/>
            </column>
            <column name="created_time" type="timestamp with time zone" defaultValueComputed="NOW()">
                <constraints nullable="false"/>
            </column>
            <column name="last_modified" type="timestamp with time zone"/>
            <column name="uploaded_by" type="varchar(256)"/>
        </createTable>

        <createSequence sequenceName="snmp_collection_sources_id_seq" startValue="1" incrementBy="1"/>

        <rollback>
            <dropTable tableName="snmp_collection_sources"/>
        </rollback>
    </changeSet>

    <!-- 3. SystemDefs (device matchers) -->
    <changeSet author="cgorantla" id="36.0.0-snmp-collection-systemdefs-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="snmp_collection_systemdefs"/>
            </not>
        </preConditions>

        <createTable tableName="snmp_collection_systemdefs">
            <column name="id" type="integer">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="collection_source_id" type="integer">
                <constraints nullable="false"
                             foreignKeyName="fk_systemdefs_source"
                             references="snmp_collection_sources(id)"
                             deleteCascade="true"/>
            </column>
            <column name="name" type="varchar(256)">
                <constraints nullable="false"/>
            </column>
            <column name="sysoid" type="varchar(256)"/>
            <column name="sysoid_mask" type="varchar(256)"/>
            <column name="ip_addresses" type="text"/>
            <column name="ip_address_masks" type="text"/>
            <column name="mib_group_names" type="text">
                <constraints nullable="false"/>
            </column>
            <column name="enabled" type="boolean" defaultValueBoolean="true">
                <constraints nullable="false"/>
            </column>
        </createTable>

        <createSequence sequenceName="snmp_collection_systemdefs_id_seq" startValue="1" incrementBy="1"/>

        <addUniqueConstraint tableName="snmp_collection_systemdefs"
                             columnNames="collection_source_id, name"
                             constraintName="uq_systemdefs_source_name"/>

        <createIndex tableName="snmp_collection_systemdefs" indexName="idx_snmp_collection_systemdefs_group">
            <column name="collection_source_id"/>
        </createIndex>

        <createIndex tableName="snmp_collection_systemdefs" indexName="idx_snmp_collection_systemdefs_sysoid">
            <column name="sysoid"/>
        </createIndex>

        <rollback>
            <dropTable tableName="snmp_collection_systemdefs"/>
        </rollback>
    </changeSet>

    <!-- 4. MIB Object Groups  -->
    <changeSet author="cgorantla" id="36.0.0-snmp-collection-mib-groups-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="snmp_collection_mib_groups"/>
            </not>
        </preConditions>

        <createTable tableName="snmp_collection_mib_groups">
            <column name="id" type="integer">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="collection_source_id" type="integer">
                <constraints nullable="false"
                             foreignKeyName="fk_mibgroups_source"
                             references="snmp_collection_sources(id)"
                             deleteCascade="true"/>
            </column>
            <column name="name" type="varchar(256)">
                <constraints nullable="false"/>
                <!-- NO UNIQUE constraint - duplicates allowed across sources -->
            </column>
            <column name="if_type" type="varchar(50)"/>
            <column name="mib_group_names" type="text"/>
            <column name="mib_objects" type="text">
                <constraints nullable="false"/>
            </column>
            <column name="mib_obj_properties" type="text"/>
            <column name="enabled" type="boolean" defaultValueBoolean="true">
                <constraints nullable="false"/>
            </column>
        </createTable>

        <createSequence sequenceName="snmp_collection_mib_groups_id_seq" startValue="1" incrementBy="1"/>

        <createIndex tableName="snmp_collection_mib_groups" indexName="idx_snmp_collection_mib_groups_group">
            <column name="collection_source_id"/>
        </createIndex>

        <createIndex tableName="snmp_collection_mib_groups" indexName="idx_mibgroups_name">
            <column name="name"/>
        </createIndex>

        <createIndex tableName="snmp_collection_mib_groups" indexName="idx_mibgroups_enabled">
            <column name="enabled"/>
        </createIndex>

        <rollback>
            <dropTable tableName="snmp_collection_mib_groups"/>
        </rollback>
    </changeSet>

    <!-- 5. Resource Types  -->
    <changeSet author="cgorantla" id="36.0.0-snmp-collection-resource-types-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="snmp_collection_resource_types"/>
            </not>
        </preConditions>

        <createTable tableName="snmp_collection_resource_types">
            <column name="id" type="integer">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="collection_source_id" type="integer">
                <constraints nullable="false"
                             foreignKeyName="fk_resourcetypes_source"
                             references="snmp_collection_sources(id)"
                             deleteCascade="true"/>
            </column>
            <column name="name" type="varchar(256)">
                <constraints nullable="false"/>
                <!-- NO UNIQUE constraint - duplicates allowed across sources -->
            </column>
            <column name="label" type="varchar(256)">
                <constraints nullable="false"/>
            </column>
            <column name="resource_label" type="varchar(512)"/>
            <column name="persistence_selector_strategy" type="varchar(256)"/>
            <column name="persistence_selector_params" type="text"/>
            <column name="storage_strategy" type="varchar(256)"/>
            <column name="storage_strategy_params" type="text"/>
            <column name="enabled" type="boolean" defaultValueBoolean="true">
                <constraints nullable="false"/>
            </column>
        </createTable>

        <createSequence sequenceName="snmp_collection_resource_types_id_seq" startValue="1" incrementBy="1"/>

        <createIndex tableName="snmp_collection_resource_types" indexName="idx_snmp_collection_resource_types_group">
            <column name="collection_source_id"/>
        </createIndex>

        <createIndex tableName="snmp_collection_resource_types" indexName="idx_resourcetypes_name">
            <column name="name"/>
        </createIndex>

        <createIndex tableName="snmp_collection_resource_types" indexName="idx_resourcetypes_enabled">
            <column name="enabled"/>
        </createIndex>

        <rollback>
            <dropTable tableName="snmp_collection_resource_types"/>
        </rollback>
    </changeSet>

    <changeSet author="cpape" id="36.0.0-eventconf-global-security-table">
        <preConditions onFail="MARK_RAN">
            <not>
                <tableExists tableName="eventconf_global_security"/>
            </not>
        </preConditions>

        <createTable tableName="eventconf_global_security">
            <column name="do_not_override" type="varchar(256)">
                <constraints primaryKey="true" nullable="false"/>
            </column>
        </createTable>
    </changeSet>

    <!-- Update nodeLostService event to include failure reason in logmsg
         and enable description update-on-reduction so alarm reflects
         the current poll failure reason -->
    <changeSet author="mmassengill" id="36.0.0-update-nodeLostService-reason-tracking">
        <preConditions onFail="MARK_RAN">
            <and>
                <tableExists tableName="eventconf_events"/>
                <sqlCheck expectedResult="1">
                    SELECT COUNT(*) FROM eventconf_events
                    WHERE uei = 'uei.opennms.org/nodes/nodeLostService'
                    AND xml_content NOT LIKE '%update-on-reduction%'
                </sqlCheck>
            </and>
        </preConditions>

        <comment>Add failure reason to nodeLostService logmsg and enable alarm description update on reduction</comment>

        <!-- Update logmsg to include the reason parameter -->
        <sql>
            UPDATE eventconf_events
            SET xml_content = REPLACE(
                xml_content,
                '%service% outage identified on interface %interface%.',
                '%service% outage identified on interface %interface%. Reason: %parm[eventReason]%'
            ),
            last_modified = NOW()
            WHERE uei = 'uei.opennms.org/nodes/nodeLostService'
            AND xml_content NOT LIKE '%update-on-reduction%';
        </sql>

        <!-- Add update-field for description on reduction -->
        <sql>
            UPDATE eventconf_events
            SET xml_content = REPLACE(
                xml_content,
                'auto-clean="false"/>',
                'auto-clean="false">&lt;update-field field-name="descr" update-on-reduction="true"/>&lt;/alarm-data>'
            ),
            last_modified = NOW()
            WHERE uei = 'uei.opennms.org/nodes/nodeLostService'
            AND xml_content LIKE '%auto-clean="false"/>%'
            AND xml_content NOT LIKE '%update-on-reduction%';
        </sql>
    </changeSet>

    <changeSet author="dino2gnt" id="36.0.0-dcb-configchanged-event">
        <preConditions onFail="MARK_RAN">
            <and>
                <tableExists tableName="eventconf_events"/>
                <sqlCheck expectedResult="0">
                    SELECT COUNT(*) FROM eventconf_events
                    WHERE uei = 'uei.opennms.org/deviceconfig/configChanged'
                </sqlCheck>
            </and>
        </preConditions>
        <sql>
            INSERT INTO eventconf_events
            (id,
             source_id,
             uei,
             event_label,
             description,
             enabled,
             xml_content,
             created_time,
             last_modified,
             modified_by,
             severity)
VALUES      (Nextval('eventconf_events_id_seq'),
             15,
             'uei.opennms.org/deviceconfig/configChanged',
             'OpenNMS-defined node event: configChanged',
             '&lt;p>Config backup changed on %service%
            during the last poll on interface %interface%.&lt;/p>',
             TRUE,
             '&lt;event xmlns="http://xmlns.opennms.org/xsd/eventconf">
&lt;uei>uei.opennms.org/deviceconfig/configChanged&lt;/uei>
&lt;event-label>OpenNMS-defined node event: configChanged&lt;/event-label>
&lt;descr>&amp;lt;p>Config backup changed on %service% during the last poll on interface %interface%.&amp;lt;/p>&lt;/descr>
&lt;logmsg dest="logndisplay">
    %service% config backup changed on interface %interface%.
&lt;/logmsg>
&lt;severity>Warning&lt;/severity>
&lt;alarm-data reduction-key="%uei%:%dpname%:%nodeid%:%interface%:%service%" alarm-type="3" auto-clean="false"/>
&lt;/event>',
             Current_timestamp,
             Current_timestamp,
             'system-migration',
             'Warning');
        </sql>
    </changeSet>
</databaseChangeLog>
