package __PACKAGE__;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.h2.tools.TriggerAdapter;

/**
 * Base class for all change-tracking triggers generated by
 * @cap-js/change-tracking. Contains the helpers shared by every trigger
 * (session variable access, skip flags, locale lookup, composition
 * dedup check, transaction id).
 *
 * Generated by @cap-js/change-tracking. Do not edit.
 */
public abstract class AbstractChangeTrackingTrigger extends TriggerAdapter {

    /** Session variable holding the global skip flag. */
    protected static final String CT_SKIP_VAR = "__CT_SKIP_VAR__";

    /**
     * Reads an H2 session variable by name. The plugin's canonical
     * session-variable names use dots (e.g. 'ct.skip_entity.X')
     * because PostgreSQL requires custom GUC options to have a
     * two-part <class>.<name> shape. H2 parses 'SELECT @a.b' as an
     * identifier separator and rejects dotted names, so we translate
     * every '.' to '_' here before reading the variable. Java
     * handlers that set these variables under CAP Java must use the
     * same underscore-only form (e.g.
     * 'SET @ct_skip_entity_sap_capire_bookshop_BookStores' = 'true').
     */
    protected String getSessionVariable(Connection conn, String name) {
        String h2Name = name.replace('.', '_');
        try (PreparedStatement stmt = conn.prepareStatement("SELECT @" + h2Name)) {
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return rs.getString(1);
                }
            }
        } catch (SQLException e) {
            /* variable not set or contains a character H2 can't parse */
        }
        return null;
    }

    protected boolean shouldSkipChangeTracking(Connection conn, String entitySkipVar) throws SQLException {
        if ("true".equals(getSessionVariable(conn, CT_SKIP_VAR))) return true;
        if ("true".equals(getSessionVariable(conn, entitySkipVar))) return true;
        return false;
    }

    protected boolean shouldSkipElement(Connection conn, String varName) throws SQLException {
        return "true".equals(getSessionVariable(conn, varName));
    }

    protected String getLocale(Connection conn) throws SQLException {
        String locale = getSessionVariable(conn, "$user.locale");
        if (locale == null || locale.isEmpty()) locale = getSessionVariable(conn, "locale");
        return locale;
    }

    protected boolean hasExistingCompositionEntry(Connection conn, String entityName, String entityKey, String attribute) throws SQLException {
        String sql = "SELECT 1 FROM sap_changelog_Changes WHERE ENTITY = ? AND ENTITYKEY = ? AND ATTRIBUTE = ? AND VALUEDATATYPE = 'cds.Composition' AND TRANSACTIONID = TRANSACTION_ID()";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, entityName);
            stmt.setString(2, entityKey);
            stmt.setString(3, attribute);
            try (ResultSet rs = stmt.executeQuery()) {
                return rs.next();
            }
        }
    }

    protected long getTransactionId(Connection conn) throws SQLException {
        try (PreparedStatement stmt = conn.prepareStatement("SELECT TRANSACTION_ID()")) {
            try (ResultSet rs = stmt.executeQuery()) {
                if (rs.next()) {
                    return rs.getLong(1);
                }
            }
        }
        return 0;
    }
}
