/*
 * 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:
//     dminsky - initial API and implementation
package org.eclipse.persistence.testing.tests.sessionbroker;

import java.util.*;

import org.eclipse.persistence.testing.framework.TestCase;

import org.eclipse.persistence.testing.models.employee.relational.EmployeeProject;
import org.eclipse.persistence.testing.models.employee.domain.Address;
import org.eclipse.persistence.testing.models.employee.domain.Employee;

import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.sessions.broker.SessionBroker;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.queries.DeleteAllQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.UpdateAllQuery;
import org.eclipse.persistence.exceptions.EclipseLinkException;

public class SessionBrokerCustomFunctionTest extends TestCase {

    protected SessionBroker sessionBroker;
    protected int testType = -1;

    public static final int READALLQUERY_TEST = 0;
    public static final int UPDATEALLQUERY_TEST = 1;
    public static final int DELETEALLQUERY_TEST = 2;

    public SessionBrokerCustomFunctionTest(int testType) {
        setDescription("Test using custom functions in a platform subclass using session broker");
        this.testType = testType;
    }

    @Override
    public void setup() {
        Project project = new EmployeeProject();
        DatabaseLogin login = ServerBrokerTestModel.getLogin1();
        login.setPlatform(new CustomDatabasePlatform());
        project.setLogin(login);

        DatabaseSession aSession = project.createDatabaseSession();
        this.sessionBroker = new SessionBroker();
        this.sessionBroker.registerSession("broker1", aSession);
        this.sessionBroker.setSessionLog(getSession().getSessionLog());
        this.sessionBroker.setLogLevel(getSession().getLogLevel());
        this.sessionBroker.login();
    }

    @Override
    public void test() {
        if (testType == READALLQUERY_TEST) {
            testReadAllQuery();
        } else if (testType == UPDATEALLQUERY_TEST) {
            testUpdateAllQuery();
        } else if (testType == DELETEALLQUERY_TEST) {
            testDeleteAllQueryTest();
        } else {
            throwError("test: Invalid test indicator passed to constructor: " + this.testType);
        }
    }

    public void testReadAllQuery() {
        try {
            UnitOfWork uow = this.sessionBroker.acquireUnitOfWork();

            ReadAllQuery query = new ReadAllQuery(Address.class);
            ExpressionBuilder builder = query.getExpressionBuilder();
            Vector<Expression> args = new Vector<Expression>();
            args.add(builder.get("country"));
            Expression expression = builder.getFunction(CustomDatabasePlatform.OPERATOR_SELECTOR, args).equal("CANADA");
            query.setSelectionCriteria(expression);

            uow.executeQuery(query);
        } catch (EclipseLinkException exception) {
            throwError("testReadAllQuery: failed to use configured platform to acquire custom function: " + exception.getMessage());
        }
    }

    public void testUpdateAllQuery() {
        try {
            DatabaseSession session = (DatabaseSession)this.sessionBroker.getSessionForName("broker1");
            session.beginTransaction();

            UnitOfWork uow = session.acquireUnitOfWork();

            UpdateAllQuery query = new UpdateAllQuery(Employee.class);
            ExpressionBuilder builder = query.getExpressionBuilder();

            Vector<Expression> args = new Vector<Expression>();
            args.add(builder.get("lastName"));

            Expression expression = builder.getFunction(CustomDatabasePlatform.OPERATOR_SELECTOR, args).equal("SMITH");
            query.setSelectionCriteria(expression);
            query.addUpdate(builder.get("lastName"), "oneincrediblyunlikelylastname");

            uow.executeQuery(query);
            uow.commit();

            session.rollbackTransaction();
        } catch (EclipseLinkException exception) {
            throwError("testUpdateAllQuery: failed to use configured platform to acquire custom function: " + exception.getMessage());
        }
    }

    public void testDeleteAllQueryTest() {
        try {
            DatabaseSession session = (DatabaseSession)this.sessionBroker.getSessionForName("broker1");
            session.beginTransaction();

            UnitOfWork uow = session.acquireUnitOfWork();

            DeleteAllQuery query = new DeleteAllQuery(Employee.class);
            ExpressionBuilder builder = query.getExpressionBuilder();

            Vector<Expression> args = new Vector<Expression>();
            args.add(builder.get("lastName"));

            Expression expression = builder.getFunction(CustomDatabasePlatform.OPERATOR_SELECTOR, args).equal("SMITH");
            query.setSelectionCriteria(expression);

            uow.executeQuery(query);
            uow.commit();

            session.rollbackTransaction();
        } catch (EclipseLinkException exception) {
            throwError("testDeleteAllQueryTest: failed to use configured platform to acquire custom function: " + exception.getMessage());
        }
    }

    @Override
    public void reset() {
        this.sessionBroker.logout();
    }

}
