<commit_before>package com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.database;

import com.bitdubai.fermat_api.FermatException;
import com.bitdubai.fermat_api.layer.all_definition.enums.CryptoCurrency;
import com.bitdubai.fermat_api.layer.all_definition.enums.interfaces.FermatEnum;
import com.bitdubai.fermat_api.layer.all_definition.events.EventSource;
import com.bitdubai.fermat_api.layer.all_definition.exceptions.InvalidParameterException;
import com.bitdubai.fermat_api.layer.all_definition.money.CryptoAddress;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.Action;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.ProtocolStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.Transaction;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.TransactionStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.CryptoStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.CryptoTransaction;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.FermatCryptoTransaction;
import com.bitdubai.fermat_api.layer.osa_android.database_system.Database;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseFilterType;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseTable;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseTableRecord;
import com.bitdubai.fermat_api.layer.osa_android.database_system.PluginDatabaseSystem;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantCreateDatabaseException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantInsertRecordException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantLoadTableToMemoryException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantOpenDatabaseException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantUpdateRecordException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.DatabaseNotFoundException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.CantInitializeIncomingIntraUserCryptoRegistryException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.IncomingIntraUserCantSaveEventException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.IncomingIntraUserExpectedTransactionNotFoundException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.util.EventWrapper;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.util.TransactionCompleteInformation;


import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * The class <code>com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.database.IncomingIntraUserDao</code>
 * hide all the details of the access to the plugin's databases.
 */
public class IncomingIntraUserDao {

    private PluginDatabaseSystem pluginDatabaseSystem;
    private Database             database;

    public IncomingIntraUserDao(PluginDatabaseSystem pluginDatabaseSystem) {
        this.pluginDatabaseSystem = pluginDatabaseSystem;
    }

    public void initialize(UUID pluginId) throws CantInitializeIncomingIntraUserCryptoRegistryException {

        if (pluginDatabaseSystem == null)
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, null, "Plugin Database System: null", "You have to set the PluginDatabaseSystem before initializing");

        try {
            this.database = this.pluginDatabaseSystem.openDatabase(pluginId, IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_DATABASE);
        } catch (DatabaseNotFoundException e) {
            IncomingIntraUserTransactionDatabaseFactory databaseFactory = new IncomingIntraUserTransactionDatabaseFactory(pluginDatabaseSystem);
            try {
                this.database = databaseFactory.createDatabase(pluginId, IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_DATABASE);
            } catch (CantCreateDatabaseException exception) {
                throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, exception, "", "Check the cause to see why the Database couldn't be created");
            }
        } catch (CantOpenDatabaseException exception) {
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, exception, "", "Check the cause to see why we couldn't open the database");
        } catch (Exception exception) {
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, FermatException.wrapException(exception), "", "Check the cause ");
        }
    }

    public void saveNewEvent(FermatEnum eventType, EventSource eventSource) throws CantInsertRecordException {
        String eventTypeAsString        = eventType.getCode();
        String eventSourceAsString      = eventSource.getCode();
        DatabaseTable eventsTable       = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        DatabaseTableRecord eventRecord = eventsTable.getEmptyRecord();

        UUID eventRecordID = UUID.randomUUID();
        long unixTime = System.currentTimeMillis();
        eventRecord.setUUIDValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME, eventRecordID);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_EVENT_COLUMN_NAME, eventTypeAsString);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME, eventSourceAsString);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "PENDING");
        eventRecord.setLongValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TIMESTAMP_COLUMN_NAME, unixTime);
        eventsTable.insertRecord(eventRecord);
    }

    public EventWrapper getNextPendingEvent(EventSource eventSource) throws CantLoadTableToMemoryException {
        DatabaseTable eventsTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        eventsTable.setStringFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "PENDING", DatabaseFilterType.EQUAL);
        eventsTable.setStringFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME, eventSource.getCode(), DatabaseFilterType.EQUAL);

        eventsTable.loadToMemory();
        eventsTable.clearAllFilters();

        List<DatabaseTableRecord> events = eventsTable.getRecords();

        if (events == null || events.isEmpty()) {
            //TODO METODO CON RETURN NULL - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG - Eliminar si molesta
            return null;
        }

        DatabaseTableRecord event = events.get(0);
        return new EventWrapper(
                event.getUUIDValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_EVENT_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME),
                event.getLongValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TIMESTAMP_COLUMN_NAME)
        );
    }

    public void disableEvent(UUID eventId) throws CantLoadTableToMemoryException, IncomingIntraUserCantSaveEventException, CantUpdateRecordException {
        DatabaseTable eventsTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        eventsTable.setUUIDFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME, eventId, DatabaseFilterType.EQUAL);

        eventsTable.loadToMemory();
        List<DatabaseTableRecord> records = eventsTable.getRecords();
        if (records == null || records.isEmpty()) {
            throw new IncomingIntraUserCantSaveEventException(IncomingIntraUserCantSaveEventException.DEFAULT_MESSAGE, null, "Event ID: " + eventId, "I couldn't find the event with the given Id");
        } else if (records.size() > 1) {
            throw new IncomingIntraUserCantSaveEventException(IncomingIntraUserCantSaveEventException.DEFAULT_MESSAGE, null, "Event ID: " + eventId, "More than one Event with the given Id");
        }
        DatabaseTableRecord eventRecord = records.get(0);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "DISABLED");
        eventsTable.updateRecord(eventRecord);
    }





    public boolean isANewTransaction(Transaction<CryptoTransaction> transaction) throws CantLoadTableToMemoryException {
        DatabaseTable registryTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        registryTable.setUUIDFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME, transaction.getTransactionID(), DatabaseFilterType.EQUAL);
        registryTable.loadToMemory();
        registryTable.clearAllFilters();
        return registryTable.getRecords().isEmpty();
    }

    public void saveTransactionAsAcknowledgedToBeNotified(Transaction<CryptoTransaction> transaction) throws CantInsertRecordException {
        saveTransactionInState(transaction, TransactionStatus.ACKNOWLEDGED, ProtocolStatus.TO_BE_NOTIFIED);
    }

    public void updateTransactionToResponsibleToBeApplied(Transaction<CryptoTransaction> transaction) throws CantUpdateRecordException, CantLoadTableToMemoryException, IncomingIntraUserExpectedTransactionNotFoundException {
        updateTransactionToState(transaction, TransactionStatus.RESPONSIBLE, ProtocolStatus.TO_BE_APPLIED);
    }

    public void updateTransactionToApplied(UUID id) throws CantLoadTableToMemoryException, IncomingIntraUserExpectedTransactionNotFoundException, CantUpdateRecordException {
        DatabaseTable registryTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord recordToUpdate = getTransactionRecordFromId(id,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME);

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_PROTOCOL_STATUS_COLUMN_NAME,
                ProtocolStatus.APPLIED.getCode()
        );
        registryTable.updateRecord(recordToUpdate);
    }

    // TODO: Completar método cuando escriba el Relay Agent. El tipo de retorno va a cambiar
    public List<TransactionCompleteInformation> getAllTransactionsToBeApplied(){
        return null;
    }



    private void saveTransactionInState(Transaction<CryptoTransaction> transaction, TransactionStatus transactionStatus, ProtocolStatus protocolStatus) throws CantInsertRecordException {
        DatabaseTable registryTable           = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord transactionRecord = registryTable.getEmptyRecord();
        fillRegistryTableRecordFromCryptoTransaction(transactionRecord, transaction, transactionStatus, protocolStatus);
        registryTable.insertRecord(transactionRecord);
    }

    private void updateTransactionToState(Transaction<CryptoTransaction> transaction, TransactionStatus transactionStatus, ProtocolStatus protocolStatus) throws CantLoadTableToMemoryException, CantUpdateRecordException, IncomingIntraUserExpectedTransactionNotFoundException {
        DatabaseTable registryTable        = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord recordToUpdate = getTransactionRecordFromId(transaction.getTransactionID(),
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME);

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TRANSACTION_STATUS_COLUMN_NAME,
                transactionStatus.getCode()
        );

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_PROTOCOL_STATUS_COLUMN_NAME,
                protocolStatus.getCode()
        );
        registryTable.updateRecord(recordToUpdate);<commit_msg>Fixing Null pointer exception caused by someone connecting this plugin<commit_after>package com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.database;

import com.bitdubai.fermat_api.FermatException;
import com.bitdubai.fermat_api.layer.all_definition.enums.CryptoCurrency;
import com.bitdubai.fermat_api.layer.all_definition.enums.interfaces.FermatEnum;
import com.bitdubai.fermat_api.layer.all_definition.events.EventSource;
import com.bitdubai.fermat_api.layer.all_definition.exceptions.InvalidParameterException;
import com.bitdubai.fermat_api.layer.all_definition.money.CryptoAddress;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.Action;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.ProtocolStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.Transaction;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.TransactionStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.CryptoStatus;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.CryptoTransaction;
import com.bitdubai.fermat_api.layer.all_definition.transaction_transference_protocol.crypto_transactions.FermatCryptoTransaction;
import com.bitdubai.fermat_api.layer.osa_android.database_system.Database;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseFilterType;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseTable;
import com.bitdubai.fermat_api.layer.osa_android.database_system.DatabaseTableRecord;
import com.bitdubai.fermat_api.layer.osa_android.database_system.PluginDatabaseSystem;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantCreateDatabaseException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantInsertRecordException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantLoadTableToMemoryException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantOpenDatabaseException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.CantUpdateRecordException;
import com.bitdubai.fermat_api.layer.osa_android.database_system.exceptions.DatabaseNotFoundException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.CantInitializeIncomingIntraUserCryptoRegistryException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.IncomingIntraUserCantSaveEventException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.exceptions.IncomingIntraUserExpectedTransactionNotFoundException;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.util.EventWrapper;
import com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.util.TransactionCompleteInformation;


import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * The class <code>com.bitdubai.fermat_dmp_plugin.layer.transaction.incoming_intra_user.developer.bitdubai.version_1.database.IncomingIntraUserDao</code>
 * hide all the details of the access to the plugin's databases.
 */
public class IncomingIntraUserDao {

    private PluginDatabaseSystem pluginDatabaseSystem;
    private Database             database;

    public IncomingIntraUserDao(PluginDatabaseSystem pluginDatabaseSystem) {
        this.pluginDatabaseSystem = pluginDatabaseSystem;
    }

    public void initialize(UUID pluginId) throws CantInitializeIncomingIntraUserCryptoRegistryException {

        if (pluginDatabaseSystem == null)
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, null, "Plugin Database System: null", "You have to set the PluginDatabaseSystem before initializing");

        try {
            this.database = this.pluginDatabaseSystem.openDatabase(pluginId, IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_DATABASE);
        } catch (DatabaseNotFoundException e) {
            IncomingIntraUserTransactionDatabaseFactory databaseFactory = new IncomingIntraUserTransactionDatabaseFactory(pluginDatabaseSystem);
            try {
                this.database = databaseFactory.createDatabase(pluginId, IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_DATABASE);
            } catch (CantCreateDatabaseException exception) {
                throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, exception, "", "Check the cause to see why the Database couldn't be created");
            }
        } catch (CantOpenDatabaseException exception) {
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, exception, "", "Check the cause to see why we couldn't open the database");
        } catch (Exception exception) {
            throw new CantInitializeIncomingIntraUserCryptoRegistryException(CantInitializeIncomingIntraUserCryptoRegistryException.DEFAULT_MESSAGE, FermatException.wrapException(exception), "", "Check the cause ");
        }
    }

    public void saveNewEvent(FermatEnum eventType, EventSource eventSource) throws CantInsertRecordException {
        String eventTypeAsString        = eventType.getCode();
        String eventSourceAsString      = eventSource.getCode();
        DatabaseTable eventsTable       = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        DatabaseTableRecord eventRecord = eventsTable.getEmptyRecord();

        UUID eventRecordID = UUID.randomUUID();
        long unixTime = System.currentTimeMillis();
        eventRecord.setUUIDValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME, eventRecordID);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_EVENT_COLUMN_NAME, eventTypeAsString);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME, eventSourceAsString);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "PENDING");
        eventRecord.setLongValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TIMESTAMP_COLUMN_NAME, unixTime);
        eventsTable.insertRecord(eventRecord);
    }

    public EventWrapper getNextPendingEvent(EventSource eventSource) throws CantLoadTableToMemoryException {
        DatabaseTable eventsTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        eventsTable.setStringFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "PENDING", DatabaseFilterType.EQUAL);
        eventsTable.setStringFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME, eventSource.getCode(), DatabaseFilterType.EQUAL);

        eventsTable.loadToMemory();
        eventsTable.clearAllFilters();

        List<DatabaseTableRecord> events = eventsTable.getRecords();

        if (events == null || events.isEmpty()) {
            //TODO METODO CON RETURN NULL - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG - Eliminar si molesta
            return null;
        }

        DatabaseTableRecord event = events.get(0);
        return new EventWrapper(
                event.getUUIDValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_EVENT_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_SOURCE_COLUMN_NAME),
                event.getStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME),
                event.getLongValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TIMESTAMP_COLUMN_NAME)
        );
    }

    public void disableEvent(UUID eventId) throws CantLoadTableToMemoryException, IncomingIntraUserCantSaveEventException, CantUpdateRecordException {
        DatabaseTable eventsTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_TABLE_NAME);
        eventsTable.setUUIDFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_ID_COLUMN_NAME, eventId, DatabaseFilterType.EQUAL);

        eventsTable.loadToMemory();
        List<DatabaseTableRecord> records = eventsTable.getRecords();
        if (records == null || records.isEmpty()) {
            throw new IncomingIntraUserCantSaveEventException(IncomingIntraUserCantSaveEventException.DEFAULT_MESSAGE, null, "Event ID: " + eventId, "I couldn't find the event with the given Id");
        } else if (records.size() > 1) {
            throw new IncomingIntraUserCantSaveEventException(IncomingIntraUserCantSaveEventException.DEFAULT_MESSAGE, null, "Event ID: " + eventId, "More than one Event with the given Id");
        }
        DatabaseTableRecord eventRecord = records.get(0);
        eventRecord.setStringValue(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_EVENTS_RECORDED_STATUS_COLUMN_NAME, "DISABLED");
        eventsTable.updateRecord(eventRecord);
    }





    public boolean isANewTransaction(Transaction<CryptoTransaction> transaction) throws CantLoadTableToMemoryException {
        DatabaseTable registryTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        registryTable.setUUIDFilter(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME, transaction.getTransactionID(), DatabaseFilterType.EQUAL);
        registryTable.loadToMemory();
        registryTable.clearAllFilters();
        return registryTable.getRecords().isEmpty();
    }

    public void saveTransactionAsAcknowledgedToBeNotified(Transaction<CryptoTransaction> transaction) throws CantInsertRecordException {
        saveTransactionInState(transaction, TransactionStatus.ACKNOWLEDGED, ProtocolStatus.TO_BE_NOTIFIED);
    }

    public void updateTransactionToResponsibleToBeApplied(Transaction<CryptoTransaction> transaction) throws CantUpdateRecordException, CantLoadTableToMemoryException, IncomingIntraUserExpectedTransactionNotFoundException {
        updateTransactionToState(transaction, TransactionStatus.RESPONSIBLE, ProtocolStatus.TO_BE_APPLIED);
    }

    public void updateTransactionToApplied(UUID id) throws CantLoadTableToMemoryException, IncomingIntraUserExpectedTransactionNotFoundException, CantUpdateRecordException {
        DatabaseTable registryTable = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord recordToUpdate = getTransactionRecordFromId(id,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME);

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_PROTOCOL_STATUS_COLUMN_NAME,
                ProtocolStatus.APPLIED.getCode()
        );
        registryTable.updateRecord(recordToUpdate);
    }

    // TODO: Completar método cuando escriba el Relay Agent. El tipo de retorno va a cambiar
    public List<TransactionCompleteInformation> getAllTransactionsToBeApplied(){
        return new ArrayList<>();
    }



    private void saveTransactionInState(Transaction<CryptoTransaction> transaction, TransactionStatus transactionStatus, ProtocolStatus protocolStatus) throws CantInsertRecordException {
        DatabaseTable registryTable           = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord transactionRecord = registryTable.getEmptyRecord();
        fillRegistryTableRecordFromCryptoTransaction(transactionRecord, transaction, transactionStatus, protocolStatus);
        registryTable.insertRecord(transactionRecord);
    }

    private void updateTransactionToState(Transaction<CryptoTransaction> transaction, TransactionStatus transactionStatus, ProtocolStatus protocolStatus) throws CantLoadTableToMemoryException, CantUpdateRecordException, IncomingIntraUserExpectedTransactionNotFoundException {
        DatabaseTable registryTable        = database.getTable(IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME);
        DatabaseTableRecord recordToUpdate = getTransactionRecordFromId(transaction.getTransactionID(),
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TABLE_NAME,
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_ID_COLUMN_NAME);

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_TRANSACTION_STATUS_COLUMN_NAME,
                transactionStatus.getCode()
        );

        recordToUpdate.setStringValue(
                IncomingIntraUserTransactionDatabaseConstants.INCOMING_INTRA_USER_REGISTRY_PROTOCOL_STATUS_COLUMN_NAME,
                protocolStatus.getCode()
        );
        registryTable.updateRecord(recordToUpdate);
{'fraction_non_alphanumeric': 0.05909797822706065, 'fraction_numerical': 0.0007069136151562279, 'mean_word_length': 6.029316770186336, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6967604', 'n_tokens_mistral': 7754, 'n_tokens_neox': 7743, 'n_words': 923}