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

import java.util.*;

import java.lang.reflect.*;

import org.eclipse.persistence.internal.sessions.remote.RemoteConnection;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.sessions.remote.RemoteSession;
import org.eclipse.persistence.testing.framework.*;

public class RemoteConnectionExceptionsTest extends TestCase {

    public RemoteConnectionExceptionsTest(int mode, Class remoteConnectionClass) {
        this.remoteConnectionClass = remoteConnectionClass;
        generator = new TransporterGenerator(mode);
        setNameAndCheckMode();
        setNamesToExclude();
        setMethodsAndArgs();
        setKnownBugs();
    }

    public RemoteConnectionExceptionsTest(int mode,
                                          String remoteConnectionClassName) throws ClassNotFoundException {
        this(mode, Class.forName(remoteConnectionClassName));
    }

    protected Class remoteConnectionClass;
    private RemoteConnection remoteConnection;
    protected TransporterGenerator generator;
    protected Object[] results;
    protected Throwable[] exceptions;

    protected Hashtable knownBugs;
    protected Vector namesToExclude;
    protected Vector methods;
    protected Vector args;

    protected void setRemoteConnection(RemoteConnection remoteConnection) {
        Class<? extends RemoteConnection> cls = remoteConnection.getClass();
        if (!remoteConnectionClass.equals(cls)) {
            throw new TestProblemException("remoteConnection's type is different from the type used to create the test");
        }
        this.remoteConnection = remoteConnection;
        this.remoteConnection.setSession(new RemoteSession());
    }

    protected RemoteConnection getRemoteConnection() {
        return remoteConnection;
    }

    protected void setNamesToExclude() {
        namesToExclude = new Vector();
        String namesToExcludeArray[] =
        { "createProxySession", "createRemoteSession", "cursoredStreamNextPage", "fixObjectReferences",
          "getRemoteSessionController", "setRemoteSessionController", };
        for (int i = 0; i < namesToExcludeArray.length; i++) {
            namesToExclude.add(namesToExcludeArray[i]);
        }
    }

    protected void setNameAndCheckMode() throws TestProblemException {
        int mode = generator.getMode();
        String className = remoteConnectionClass.getName();
        if (mode == TransporterGenerator.THROW_REMOTE_EXCEPTION) {
            setName(getName().concat(" THROW_REMOTE_EXCEPTION"));
            setDescription("Verifies that CommunicationException are thrown by methods of " + className +
                           " class");
        } else if (mode == TransporterGenerator.SET_EXCEPTION_INTO_TRANSPORTER) {
            setName(getName().concat(" SET_EXCEPTION_INTO_TRANSPORTER"));
            setDescription("Verifies that Transporter.getException() are thrown by methods of " + className +
                           " class");
        } else {
            throw new TestProblemException("Unsupported mode");
        }
    }

    protected void setMethodsAndArgs() {
        methods = new Vector();
        args = new Vector();
        Method[] allMethods = remoteConnectionClass.getMethods();
        for (int i = 0; i < allMethods.length; i++) {
            Method method = allMethods[i];
            if (!method.getDeclaringClass().equals(remoteConnectionClass)) {
                continue;
            }
            if (!Modifier.isPublic(method.getModifiers())) {
                continue;
            }
            String name = method.getName();
            if (namesToExclude != null && namesToExclude.contains(name)) {
                continue;
            }
            methods.add(method);

            Class[] types = method.getParameterTypes();
            Object[] params = new Object[types.length];
            for (int j = 0; j < types.length; j++) {
                Class type = types[j];
                if (type.isPrimitive()) {
                    params[j] = getWrapperClassInstance(type);
                }
            }
            args.add(params);
        }
    }

    protected void setKnownBugs() {
        knownBugs = new Hashtable();
        if (generator.getMode() == TransporterGenerator.SET_EXCEPTION_INTO_TRANSPORTER) {
            for (int i = 0; i < methods.size(); i++) {
                Method method = (Method)methods.elementAt(i);
                Object[] params = (Object[])args.elementAt(i);
                String name = method.getName();
                if (name.equals("cursorSelectObjects")) {
                    if (params.length == 2) {
                        knownBugs.put(method, "bug 2909926");
                    }
                }
            }
        }
    }

    protected String getNameToBind() {
        return this.getClass().getName();
    }

    protected boolean isCorrect(int i) {
        Throwable exception = exceptions[i];
        boolean ok;
        int mode = generator.getMode();
        if (mode == TransporterGenerator.THROW_REMOTE_EXCEPTION) {
            ok = exception != null;
            if (ok) {
                ok = CommunicationException.class.isInstance(exception);
                if (ok) {
                    ok =
 ((CommunicationException)exception).getErrorCode() == CommunicationException.ERROR_IN_INVOCATION;
                }
            }
            if (!ok) {
                if (((Method)methods.elementAt(i)).getName().equals("isConnected")) {
                    if (Boolean.class.isInstance(results[i])) {
                        ok = !(Boolean) results[i];
                    }
                }
            }
        } else if (mode == TransporterGenerator.SET_EXCEPTION_INTO_TRANSPORTER) {
            ok = exception != null;
            if (ok) {
                ok = TestException.class.isInstance(exception);
                if (ok) {
                    ok = exception.getMessage().endsWith(generator.getMessage());
                }
            }
        } else {
            throw new TestException("Unsupported mode");
        }
        return ok;
    }

    @Override
    public void test() throws Exception {
        results = new Object[methods.size()];
        exceptions = new Throwable[methods.size()];
        for (int i = 0; i < methods.size(); i++) {
            Method method = (Method)methods.elementAt(i);
            Object[] params = (Object[])args.elementAt(i);
            Object result = null;
            Throwable exception = null;
            try {
                result = method.invoke(getRemoteConnection(), params);
            } catch (InvocationTargetException ex) {
                exception = ex.getTargetException();
            }
            results[i] = result;
            exceptions[i] = exception;
        }
    }

    @Override
    public void verify() {
        boolean errorHasOccured = false;
        String errorMessage = new String("Wrong exception/result thrown/returned by methods:");
        String unknownBug = new String("!!!UNKNOWN BUG!!!");
        for (int i = 0; i < methods.size(); i++) {
            Method method = (Method)methods.elementAt(i);
            String name = method.getName();
            if (!isCorrect(i)) {
                errorHasOccured = true;
                errorMessage = errorMessage.concat(" ");
                errorMessage = errorMessage.concat(name);
                errorMessage = errorMessage.concat("(");
                String bug = unknownBug;
                if (knownBugs != null && !knownBugs.isEmpty()) {
                    String knownBug = (String)knownBugs.get(methods.elementAt(i));
                    if (knownBug != null) {
                        bug = knownBug;
                    }
                }
                errorMessage = errorMessage.concat(bug);
                errorMessage = errorMessage.concat(")");
                errorMessage = errorMessage.concat(";");
            }
        }
        if (errorHasOccured) {
            throw new TestErrorException(errorMessage);
        }
    }

    public static Object getWrapperClassInstance(Class cls) {
        if (Integer.TYPE.equals(cls)) {
            return 0;
        } else if (Boolean.TYPE.equals(cls)) {
            return Boolean.FALSE;
        } else if (Character.TYPE.equals(cls)) {
            return ' ';
        } else if (Byte.TYPE.equals(cls)) {
            byte b = 0;
            return b;
        } else if (Short.TYPE.equals(cls)) {
            short s = 0;
            return s;
        } else if (Long.TYPE.equals(cls)) {
            return 0L;
        } else if (Float.TYPE.equals(cls)) {
            return (float) 0;
        } else if (Double.TYPE.equals(cls)) {
            return (double) 0;
        } else {
            return null;
        }
    }
}
