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

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Vector;

/**
 * <p>Purpose<b></b>:Creates several variations of the passed TestCase
 * (or of each member of a Vector of TestCases) using all combinations
 * of values of the specified boolean attributes on the specified object.
 * Suppose we want to run an existing test with four different DatabasePlatform settings:
 * shouldBindAllParameters  shouldCacheAllStatements
 * false                    false
 * false                    true
 * true                     false
 * true                     true
 * All we should do is to substitute:
 *      testSuite.addTest(test);
 * for:
 *      Object obj = getSession().getPlatform();
 *      String str = "shouldBindAllParameters shouldCacheAllStatements"
 *      testSuite.addTests(TestVariation.get(obj, str, test));
 * The attributes names should be separated by a space.
 * Reflection is used to find a getter and a setter for the specified attribute:
 * the list of all the methods with appropriate signature is examined, and the first
 * method with a name containing the specified name (case insensitive comparison) is used.
 * Therefore if the name passed is "foo", both "getFoo" and "setFoo" will be found,
 * but if there also a "getFooo" and "setFooo" methods, they could be wrongly picked up.
 * If the getter/setter pair, or a field for the specified name is not found,
 * a TestWarningException is thrown.
 */
public class TestVariation {
    protected static char separator = ' ';

    public static Vector get(Object object, String str, TestCase test) {
        Vector testsIn = new Vector(1);
        testsIn.add(test);
        return get(object, str, testsIn);
    }

    public static Vector get(Object object, String str, Vector testsIn) {
        Vector names = getNames(str);
        Vector testsOut = new Vector();
        if (names.isEmpty() || testsIn.isEmpty()) {
            return testsOut;
        }
        Vector getters = new Vector();
        Vector setters = new Vector();
        Vector fields = new Vector();
        getMembers(object.getClass(), names, getters, setters, fields, true);
        int numberOfTests = (int)java.lang.Math.pow(2, names.size());
        for (int i = 0; i < numberOfTests; i++) {
            Enumeration enumtr = testsIn.elements();
            while (enumtr.hasMoreElements()) {
                TestWrapper testWrapper = createTest(i, object, names, getters, setters, fields, (TestCase)enumtr.nextElement());
                testsOut.addElement(testWrapper);
            }
        }
        return testsOut;
    }

    protected static Vector getNames(String str) {
        Vector names = new Vector();
        String[] strPair = splitString(str);
        while (strPair[0] != null) {
            names.addElement(strPair[0]);
            strPair = splitString(strPair[1]);
        }
        return names;
    }

    protected static InnerTestWrapper createTest(int index, Object object, Vector names, Vector getters, Vector setters, Vector fields, TestCase test) {
        boolean[] values = new boolean[names.size()];
        int i = 0;
        while (index > 0) {
            values[i] = (index % 2) == 1;
            i++;
            index = index / 2;
        }
        String[] namesArray = new String[names.size()];
        namesArray = (String[])names.toArray(namesArray);
        Method[] gettersArray = new Method[names.size()];
        gettersArray = (Method[])getters.toArray(gettersArray);
        Method[] settersArray = new Method[names.size()];
        settersArray = (Method[])setters.toArray(settersArray);
        Field[] fieldsArray = new Field[names.size()];
        fieldsArray = (Field[])fields.toArray(fieldsArray);
        return new InnerTestWrapper(test, object, values, namesArray, gettersArray, settersArray, fieldsArray);
    }

    protected static String[] splitString(String str) {
        String[] out = new String[2];
        out[0] = null;
        out[1] = null;
        if (str == null) {
            return out;
        }

        int first = -1;
        int lastPlusOne = str.length();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (first == -1) {
                if (ch != separator) {
                    first = i;
                }
            } else {
                if (ch == separator) {
                    lastPlusOne = i;
                    break;
                }
            }
        }
        if (first == -1) {
            return out;
        }

        out[0] = str.substring(first, lastPlusOne);
        out[1] = str.substring(lastPlusOne, str.length());

        return out;
    }

    protected static void getMembers(Class cls, Vector names, Vector getters, Vector setters, Vector fields, boolean throwExceptionIfNotFound) {
        Method[] allMethods = cls.getMethods();
        Field[] allFields = cls.getFields();

        Vector candidateGetters = new Vector();
        Vector candidateSetters = new Vector();
        Vector candidateFields = new Vector();

        // Need those to save lower case names
        Vector candidateGettersNames = new Vector();
        Vector candidateSettersNames = new Vector();
        Vector candidateFieldsNames = new Vector();

        for (int i = 0; i < allMethods.length; i++) {
            Class returnType = allMethods[i].getReturnType();
            Class[] parameterTypes = allMethods[i].getParameterTypes();
            if (returnType.equals(boolean.class) && (parameterTypes.length == 0)) {
                candidateGetters.addElement(allMethods[i]);
                candidateGettersNames.addElement(allMethods[i].getName().toLowerCase());
            } else if (returnType.equals(void.class) && (parameterTypes.length == 1)) {
                if (parameterTypes[0].equals(boolean.class)) {
                    candidateSetters.addElement(allMethods[i]);
                    candidateSettersNames.addElement(allMethods[i].getName().toLowerCase());
                }
            }
        }
        for (int i = 0; i < allFields.length; i++) {
            Class type = allFields[i].getType();
            if (type.equals(boolean.class)) {
                candidateFields.addElement(allFields[i]);
                candidateFieldsNames.addElement(allFields[i].getName().toLowerCase());
            }
        }
        for (int i = 0; i < names.size(); i++) {
            Object getter = null;
            Object setter = null;
            Object field = null;
            String name = ((String)names.elementAt(i)).toLowerCase();
            for (int j = 0; j < candidateGetters.size(); j++) {
                if (((String)candidateGettersNames.elementAt(j)).indexOf(name) != -1) {
                    getter = candidateGetters.elementAt(j);
                    candidateGetters.remove(j);
                    candidateGettersNames.remove(j);
                    break;
                }
            }
            for (int j = 0; j < candidateSetters.size(); j++) {
                if (((String)candidateSettersNames.elementAt(j)).indexOf(name) != -1) {
                    setter = candidateSetters.elementAt(j);
                    candidateSetters.remove(j);
                    candidateSettersNames.remove(j);
                    break;
                }
            }
            for (int j = 0; j < candidateFields.size(); j++) {
                if (((String)candidateFieldsNames.elementAt(j)).indexOf(name) != -1) {
                    field = candidateFields.elementAt(j);
                    candidateFields.remove(j);
                    candidateFieldsNames.remove(j);
                    break;
                }
            }
            if ((field != null) || ((setter != null) && (getter != null))) {
                setters.add(setter);
                getters.add(getter);
                fields.add(field);
            } else {
                if (throwExceptionIfNotFound) {
                    throw new TestWarningException("Can't find a setter/getter or field for " + names.elementAt(i));
                } else {
                    names.remove(i);
                    i--;
                }
            }
        }
    }

    protected static class InnerTestWrapper extends TestWrapper {
        protected Object object;
        private Field[] fields;
        private Method[] getters;
        private Method[] setters;
        private boolean[] required;
        private boolean[] original;

        public InnerTestWrapper(TestCase test, Object object, boolean[] values, String[] names, Method[] getters, Method[] setters, Field[] fields) {
            super(test);
            this.object = object;
            original = new boolean[values.length];
            required = new boolean[values.length];
            this.getters = getters;
            this.setters = setters;
            this.fields = fields;
            System.arraycopy(values, 0, required, 0, values.length);
            for (int i = 0; i < values.length; i++) {
                String name;
                if (fields[i] != null) {
                    name = fields[i].getName();
                } else {
                    name = names[i];
                }
                setName(getName() + " " + name + "=" + values[i]);
            }
        }

        @Override
        protected void setup() throws Throwable {
            for (int i = 0; i < required.length; i++) {
                if (getters[i] != null) {
                    Object[] args = {  };
                    Boolean res = (Boolean)getters[i].invoke(object, args);
                    original[i] = res;
                } else {
                    original[i] = fields[i].getBoolean(object);
                }

                if (setters[i] != null) {
                    Object[] args = {required[i]};
                    setters[i].invoke(object, args);
                } else {
                    fields[i].setBoolean(object, required[i]);
                }
            }
            super.setup();
        }

        @Override
        public void reset() throws Throwable {
            super.reset();
            for (int i = required.length - 1; i >= 0; i--) {
                if (setters[i] != null) {
                    Object[] args = {original[i]};
                    setters[i].invoke(object, args);
                } else {
                    fields[i].setBoolean(object, original[i]);
                }
            }
        }
    }
}
