/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.feature;

import java.io.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sequencing.*;
import org.eclipse.persistence.tools.schemaframework.*;
import org.eclipse.persistence.sessions.*;

/**
 * Test custom sequence-table access
 */
public class CustomSequenceTest extends AutoVerifyTestCase {

    /** the original setting */
    private Sequence originalSequence;

    /** the new sequence table name */
    private String newSeqTableName;

    /** the initial value of the counter for EMP_SEQ in the new table */
    private int initialSeqCount;

    /** the Employee being inserted using the new Seq Table */
    private Employee newEmployee;

    public CustomSequenceTest() {
        setDescription("This test verifies that sequencing can be customized using setUpdateSequenceQuery(DataModifyQuery) and setSelectSequenceNumberQuery(ValueReadQuery).");
    }

    protected void buildNEW_SEQUENCETable() {
        TableDefinition tabledefinition = new TableDefinition();

        // SECTION: TABLE
        tabledefinition.setName(this.newSeqTableName);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field = new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field.setName("SEQ_NAME");
        field.setType(String.class);
        field.setSize(50);
        field.setShouldAllowNull(true);
        field.setIsPrimaryKey(false);
        field.setUnique(false);
        field.setIsIdentity(false);
        tabledefinition.addField(field);

        // SECTION: FIELD
        org.eclipse.persistence.tools.schemaframework.FieldDefinition field1 = new org.eclipse.persistence.tools.schemaframework.FieldDefinition();
        field1.setName("SEQ_COUNT");
        field1.setType(Long.class);
        field1.setSize(15);
        field1.setShouldAllowNull(true);
        field1.setIsPrimaryKey(false);
        field1.setUnique(false);
        field1.setIsIdentity(false);
        tabledefinition.addField(field1);

        new SchemaManager((DatabaseSession)getSession()).replaceObject(tabledefinition);
    }

    @Override
    public void reset() {
        rollbackTransaction();
        getSession().getIdentityMapAccessor().initializeIdentityMaps();

        // Change Sequence Query stuff back to normal
        getSession().getProject().getLogin().setDefaultSequence(this.originalSequence);
        // Don't want the sequence numbers obtained from another sequence table to be used with the regular one.
        // Note that before rollbackTransaction used to wipe out all sequencing numbers, but now
        // sequencing numbers remain no matter how transaction ends (unless there is no separate sequencing
        // connection used)
        ((DatabaseSession)getSession()).getSequencingControl().initializePreallocated();
    }

    @Override
    public void setup() {
        org.eclipse.persistence.internal.databaseaccess.DatabasePlatform p = getSession().getProject().getLogin().getPlatform();

        /**
         * Build another sequence table for our custom sequencing.
         */
        this.newSeqTableName = new String("NEW_SEQUENCE");
        this.initialSeqCount = 1233;
        buildNEW_SEQUENCETable();
        getSession().executeNonSelectingCall(new org.eclipse.persistence.queries.SQLCall("INSERT INTO " + this.newSeqTableName + "(" + p.getSequenceNameFieldName() + ", " + p.getSequenceCounterFieldName() + ") values ('EMP_SEQ', " + this.initialSeqCount + ")"));

        /**
         * Set the Sequence Query Stuff to use our new sequence table.
         */
        // Save the old settings
        this.originalSequence = getSession().getLogin().getDefaultSequence();

        // Build the new custom queries
        DataModifyQuery newUpdateSeqQuery = new DataModifyQuery();
        newUpdateSeqQuery.addArgument("seqName");
        StringWriter writer1 = new StringWriter();
        writer1.write("UPDATE " + this.newSeqTableName);
        writer1.write(" SET " + p.getSequenceCounterFieldName());
        writer1.write(" = " + p.getSequenceCounterFieldName());
        writer1.write(" + " + p.getSequencePreallocationSize());
        writer1.write(" WHERE " + p.getSequenceNameFieldName());
        writer1.write(" = #seqName");
        newUpdateSeqQuery.setSQLString(writer1.toString());

        ValueReadQuery newSelectSeqNumQuery = new ValueReadQuery();
        newSelectSeqNumQuery.addArgument("seqName");
        StringWriter writer2 = new StringWriter();
        writer2.write("SELECT " + p.getSequenceCounterFieldName());
        writer2.write(" FROM " + this.newSeqTableName);
        writer2.write(" WHERE " + p.getSequenceNameFieldName());
        writer2.write(" = #seqName");
        newSelectSeqNumQuery.setSQLString(writer2.toString());

        // Set the new queries
        QuerySequence newSequence = new QuerySequence();
        newSequence.setUpdateQuery(newUpdateSeqQuery);
        newSequence.setSelectQuery(newSelectSeqNumQuery);
        getSession().getLogin().setDefaultSequence(newSequence);
        ((DatabaseSession)getSession()).getSequencingControl().resetSequencing();
        ((DatabaseSession)getSession()).getSequencingControl().initializePreallocated();
    }

    @Override
    public void test() {
        beginTransaction();

        // write a new Employee to the DB
        this.newEmployee = new org.eclipse.persistence.testing.models.employee.domain.Employee();
        this.newEmployee.setFirstName("Brendan");
        this.newEmployee.setLastName("Rickey");
        UnitOfWork uow1 = getSession().acquireUnitOfWork();
        uow1.registerObject(this.newEmployee);
        uow1.commit();

        // update the Employee
        UnitOfWork uow2 = getSession().acquireUnitOfWork();
        Employee empRead = (Employee)uow2.readObject(this.newEmployee);
        empRead.setFirstName("Object");
        empRead.setLastName("People");
        uow2.commit();
    }

    @Override
    public void verify() {
        //make sure the Employee was inserted and updated, and that the new Seq table was used.
        Employee verifyEmp = (Employee)getSession().readObject(this.newEmployee);
        if (verifyEmp.getId().intValue() != (this.initialSeqCount + 1)) {
            throw new TestErrorException("The new Sequence Table was not used! " + verifyEmp.getId());
        }
    }
}
