/*
 * 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.sessionsxml;

import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.sequencing.DefaultSequence;
import org.eclipse.persistence.sequencing.NativeSequence;
import org.eclipse.persistence.sequencing.Sequence;
import org.eclipse.persistence.sequencing.TableSequence;
import org.eclipse.persistence.sequencing.UnaryTableSequence;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;


/**
 * Tests sequencing loading in session xml file that is built and validated against the
 * XML Schema
 *
 * @author Andrei Ilitchev
 * @version 1.0
 */
public class SessionsXMLSchemaSequencingTest extends AutoVerifyTestCase {
    final int numSessions = 4;
    DatabaseSession[] session = new DatabaseSession[numSessions];
    String[] sessionName = { "NoDefaultSequence_NoSequences", "DefaultSequence_NoSequences", "NoDefaultSequence_Sequences", "DefaultSequence_Sequences" };
    Sequence definedDefaultSequence;
    HashMap definedSequences = new HashMap();

    public SessionsXMLSchemaSequencingTest() {
        setDescription("Test loading of sequencing in session xml against the XML Schema");
        definedDefaultSequence = new TableSequence("", 25, "MY_SEQUENCE", "MY_SEQ_NAME", "MY_SEQ_COUNT");
        definedSequences.put("EMP_SEQ", new DefaultSequence("EMP_SEQ", 30));
        definedSequences.put("PROJ_SEQ", new NativeSequence("PROJ_SEQ", 35));
        definedSequences.put("ADDRESS_SEQ", new UnaryTableSequence("ADDRESS_SEQ", 40));
    }

    @Override
    public void reset() {
        for (int i = 0; i < numSessions; i++) {
            if (session[i] != null) {
                SessionManager.getManager().getSessions().remove(session[i]);
                session[i] = null;
            }
        }
    }

    @Override
    protected void setup() throws Exception {
        XMLSessionConfigLoader loader = new XMLSessionConfigLoader("org/eclipse/persistence/testing/models/sessionsxml/XMLSchemaSessionSequencing.xml");
        for (int i = 0; i < numSessions; i++) {
            session[i] = (DatabaseSession)SessionManager.getManager().getSession(loader, sessionName[i], getClass().getClassLoader(), false, true);
        }
    }

    @Override
    protected void verify() {
        for (int i = 0; i < numSessions; i++) {
            boolean isDefaultSequenceDefined = sessionName[i].indexOf("NoDefaultSequence") == -1;
            boolean isSequencesDefined = sessionName[i].indexOf("NoSequences") == -1;
            boolean ok;
            if (isDefaultSequenceDefined) {
                ok = definedDefaultSequence.equals(session[i].getDatasourcePlatform().getDefaultSequence());
            } else {
                ok = !((DatasourcePlatform)session[i].getDatasourcePlatform()).hasDefaultSequence();
            }
            if (!ok) {
                throw new TestErrorException("Session " + sessionName[i] + " has wrong defaultSequence");
            }

            if (isSequencesDefined) {
                Iterator it = definedSequences.values().iterator();
                while (it.hasNext()) {
                    Sequence definedSequence = (Sequence)it.next();
                    Sequence sequence = session[i].getDatasourcePlatform().getSequence(definedSequence.getName());
                    ok = definedSequence.equals(sequence);
                    if (!ok) {
                        throw new TestErrorException("Session " + sessionName[i] + " has wrong " + sequence.getName() + " sequence");
                    }
                }
            } else {
                ok = session[i].getDatasourcePlatform().getSequences() == null || session[i].getDatasourcePlatform().getSequences().isEmpty();
                if (!ok) {
                    throw new TestErrorException("Session " + sessionName[i] + " has sequences, but it's not supposed to.");
                }
            }
        }
    }
}
