/*
 * Copyright (c) 2017, 2018 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.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.s1asdev.jdbc.maxconnectionusage.client;

import javax.naming.*;

import com.sun.s1asdev.jdbc.maxconnectionusage.ejb.SimpleBMPHome;
import com.sun.s1asdev.jdbc.maxconnectionusage.ejb.SimpleBMP;
import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

import java.rmi.RemoteException;

public class Client {

    SimpleReporterAdapter stat = new SimpleReporterAdapter();

    public static void main(String[] args)
            throws Exception {

        Client client = new Client();
        client.runTest();
    }

    public void runTest() throws Exception {
        InitialContext ic = new InitialContext();
        Object objRef = ic.lookup("java:comp/env/ejb/SimpleBMPHome");
        SimpleBMPHome simpleBMPHome = (SimpleBMPHome)
                javax.rmi.PortableRemoteObject.narrow(objRef, SimpleBMPHome.class);

        SimpleBMP simpleBMP = simpleBMPHome.create();
        stat.addDescription("Max Connection Usage");

        if (simpleBMP.test1(false)) {
            stat.addStatus(" Max Connection Usage -  (local-TxNotSupported): ", stat.PASS);
        } else {
            stat.addStatus(" Max Connection Usage -  (local-TxNotSupported): ", stat.FAIL);
        }

        boolean useXA = false;
        boolean status = connectionSharingTest(simpleBMP, useXA, 21112);
        if (status) {
            stat.addStatus(" Max Connection Usage - (local-Tx-Sharing) : ", stat.PASS);
        } else {
            stat.addStatus(" Max Connection Usage - (local-Tx-Sharing) : ", stat.FAIL);
        }


        if (simpleBMP.test1(true)) {
            stat.addStatus(" Max Connection Usage -  (XA-TxNotSupported) : ", stat.PASS);
        } else {
            stat.addStatus(" Max Connection Usage -  (XA-TxNotSupported) : ", stat.FAIL);
        }

        //Commented as this test is not valid.
        //physical connection (ds.getConnection(conn)) will be different each time.
        
        /*useXA = true;
        status = connectionSharingTest(simpleBMP, useXA, 12221);

        if (status) {
            stat.addStatus(" Max Connection Usage - (XA-Tx-Sharing) : ", stat.PASS);
        } else {
            stat.addStatus(" Max Connection Usage - (XA-Tx-Sharing) : ", stat.FAIL);
        }*/

        stat.printSummary();
    }

    private boolean connectionSharingTest(SimpleBMP simpleBMP, boolean useXA, int value) throws RemoteException {
        String results[] = new String[10];
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                results[i] = simpleBMP.test2(useXA, value);
            } else {
                results[i] = simpleBMP.test3((i / 2) + 1, useXA, value);
            }
        }
        boolean status = true;
        String result = results[0];
        for (int i = 0; i < results.length; i++) {
            if (!results[i].equalsIgnoreCase(result)) {
                System.out.println("Result 0 : " + result);
                System.out.println("Result " + i + " : " + results[i]);
                status = false;
                break;
            }
        }

        String result2 = simpleBMP.test2(useXA, value);

        if (!result2.equalsIgnoreCase(result) && status ) {
            status = true;
        } else {
            System.out.println("Marking status as false during verification");
            System.out.println("is XA : " + useXA);
            System.out.println("Value : " + value);
            System.out.println("Result 1 : " + result);
            System.out.println("Result 2 : " + result2);
            status = false;
        }
        return status;
    }
}
