/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;

/**
 * Smali exercise.
 */
public class Main {

    private static class TestCase {
        public TestCase(String testName, String testClass, String testMethodName, Object[] values,
                        Throwable expectedException, Object expectedReturn,
                        boolean checkCompiled) {
            this.testName = testName;
            this.testClass = testClass;
            this.testMethodName = testMethodName;
            this.values = values;
            this.expectedException = expectedException;
            this.expectedReturn = expectedReturn;
            this.checkCompiled = checkCompiled;
        }

        public TestCase(String testName, String testClass, String testMethodName, Object[] values,
                        Throwable expectedException, Object expectedReturn) {
            this(testName, testClass, testMethodName, values, expectedException,
                 expectedReturn, false);
        }

        String testName;
        String testClass;
        String testMethodName;
        Object[] values;
        Throwable expectedException;
        Object expectedReturn;
        boolean checkCompiled;
    }

    private List<TestCase> testCases;

    public Main() {
        // Create the test cases.
        testCases = new LinkedList<TestCase>();
        testCases.add(new TestCase("PackedSwitch", "PackedSwitch", "packedSwitch",
                new Object[]{123}, null, 123));
        testCases.add(new TestCase("PackedSwitch key INT_MAX", "PackedSwitch",
                "packedSwitch_INT_MAX", new Object[]{123}, null, 123));
        testCases.add(new TestCase("PackedSwitch key overflow", "b_24399945",
                "packedSwitch_overflow", new Object[]{123}, new VerifyError(), null));

        testCases.add(new TestCase("b/17790197", "B17790197", "getInt", null, null, 100));
        testCases.add(new TestCase("FloatBadArgReg", "FloatBadArgReg", "getInt",
                new Object[]{100}, null, 100));
        testCases.add(new TestCase("negLong", "negLong", "negLong", null, null, 122142L));
        testCases.add(new TestCase("sameFieldNames", "sameFieldNames", "getInt", null, null, 7));
        testCases.add(new TestCase("b/18380491", "B18380491ConcreteClass", "foo",
                new Object[]{42}, null, 42));
        testCases.add(new TestCase("invoke-super abstract", "B18380491ConcreteClass", "foo",
                new Object[]{0}, new AbstractMethodError(), null));
        testCases.add(new TestCase("BadCaseInOpRegRegReg", "BadCaseInOpRegRegReg", "getInt", null,
                null, 2));
        testCases.add(new TestCase("CmpLong", "CmpLong", "run", null, null, 0));
        testCases.add(new TestCase("FloatIntConstPassing", "FloatIntConstPassing", "run", null,
                null, 2));
        testCases.add(new TestCase("b/18718277", "B18718277", "getInt", null, null, 0));
        testCases.add(new TestCase("b/18800943 (1)", "B18800943_1", "n_a", null, new VerifyError(),
                0));
        testCases.add(new TestCase("b/18800943 (2)", "B18800943_2", "n_a", null, new VerifyError(),
                0));
        testCases.add(new TestCase("MoveExc", "MoveExc", "run", null, new ArithmeticException(),
                null));
        testCases.add(new TestCase("MoveExceptionOnEntry", "MoveExceptionOnEntry",
            "moveExceptionOnEntry", new Object[]{0}, new VerifyError(), null));
        testCases.add(new TestCase("EmptySparseSwitch", "EmptySparseSwitch", "run", null, null,
                null));
        testCases.add(new TestCase("b/20224106", "B20224106", "run", null, new VerifyError(),
                0));
        testCases.add(new TestCase("b/17410612", "B17410612", "run", null, new VerifyError(),
                0));
        testCases.add(new TestCase("b/21863767", "B21863767", "run", null, null,
                null));
        testCases.add(new TestCase("b/21873167", "B21873167", "test", null, null, null));
        testCases.add(new TestCase("b/21614284", "B21614284", "test", new Object[] { null },
                new NullPointerException(), null));
        testCases.add(new TestCase("b/21902684", "B21902684", "test", null, null, null));
        testCases.add(new TestCase("b/22045582", "B22045582", "run", null, new VerifyError(),
                0));
        testCases.add(new TestCase("b/22045582 (int)", "B22045582Int", "run", null,
                new VerifyError(), 0));
        testCases.add(new TestCase("b/22045582 (wide)", "B22045582Wide", "run", null,
                new VerifyError(), 0));
        testCases.add(new TestCase("b/21886894", "B21886894", "test", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/22080519", "B22080519", "run", null,
                new NullPointerException(), null));
        testCases.add(new TestCase("b/21645819", "B21645819", "run", new Object[] { null },
                null, null));
        testCases.add(new TestCase("b/22244733", "B22244733", "run", new Object[] { "abc" },
                null, "abc"));
        testCases.add(new TestCase("b/22331663", "B22331663", "run", new Object[] { false },
                null, null));
        testCases.add(new TestCase("b/22331663 (pass)", "B22331663Pass", "run",
                new Object[] { false }, null, null));
        testCases.add(new TestCase("b/22331663 (fail)", "B22331663Fail", "run",
                new Object[] { false }, new VerifyError(), null));
        testCases.add(new TestCase("b/22411633 (1)", "B22411633_1", "run", new Object[] { false },
                null, null));
        testCases.add(new TestCase("b/22411633 (2)", "B22411633_2", "run", new Object[] { false },
                new VerifyError(), null));
        testCases.add(new TestCase("b/22411633 (3)", "B22411633_3", "run", new Object[] { false },
                null, null));
        testCases.add(new TestCase("b/22411633 (4)", "B22411633_4", "run", new Object[] { false },
                new VerifyError(), null));
        testCases.add(new TestCase("b/22411633 (5)", "B22411633_5", "run", new Object[] { false },
                null, null));
        testCases.add(new TestCase("b/22777307", "B22777307", "run", null, new InstantiationError(),
                null));
        testCases.add(new TestCase("b/22881413", "B22881413", "run", null, null, null));
        testCases.add(new TestCase("b/20843113", "B20843113", "run", null, null, null));
        testCases.add(new TestCase("b/23201502 (float)", "B23201502", "runFloat", null,
                new NullPointerException(), null));
        testCases.add(new TestCase("b/23201502 (double)", "B23201502", "runDouble", null,
                new NullPointerException(), null));
        testCases.add(new TestCase("b/23300986", "B23300986", "runAliasAfterEnter",
                new Object[] { new Object() }, null, null));
        testCases.add(new TestCase("b/23300986 (2)", "B23300986", "runAliasBeforeEnter",
                new Object[] { new Object() }, null, null));
        testCases.add(new TestCase("b/23502994 (if-eqz)", "B23502994", "runIF_EQZ",
                new Object[] { new Object() }, null, null));
        testCases.add(new TestCase("b/23502994 (check-cast)", "B23502994", "runCHECKCAST",
                new Object[] { "abc" }, null, null));
        testCases.add(new TestCase("b/25494456", "B25494456", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/21869691", "B21869691A", "run", null,
                new IncompatibleClassChangeError(), null));
        testCases.add(new TestCase("b/26143249", "B26143249", "run", null,
                new AbstractMethodError(), null));
        testCases.add(new TestCase("b/26579108", "B26579108", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (1)", "B26594149_1", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (2)", "B26594149_2", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (3)", "B26594149_3", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (4)", "B26594149_4", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (5)", "B26594149_5", "run", null, null, null));
        testCases.add(new TestCase("b/26594149 (6)", "B26594149_6", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (7)", "B26594149_7", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26594149 (8)", "B26594149_8", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/27148248", "B27148248", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/26965384", "B26965384", "run", null, new VerifyError(),
                null));
        testCases.add(new TestCase("b/27799205 (1)", "B27799205Helper", "run1", null, null, null));
        testCases.add(new TestCase("b/27799205 (2)", "B27799205Helper", "run2", null,
                new VerifyError(), null));
        testCases.add(new TestCase("b/27799205 (3)", "B27799205Helper", "run3", null,
                new VerifyError(), null));
        testCases.add(new TestCase("b/27799205 (4)", "B27799205Helper", "run4", null,
                new VerifyError(), null));
        testCases.add(new TestCase("b/27799205 (5)", "B27799205Helper", "run5", null,
                new VerifyError(), null));
        testCases.add(new TestCase("b/27799205 (6)", "B27799205Helper", "run6", null, null, null));
        testCases.add(new TestCase("b/28187158", "B28187158", "run", new Object[] { null },
                new VerifyError(), null));
        testCases.add(new TestCase("b/29778499 (1)", "B29778499_1", "run", null,
                new IncompatibleClassChangeError(), null));
        testCases.add(new TestCase("b/29778499 (2)", "B29778499_2", "run", null,
                new IncompatibleClassChangeError(), null));
        testCases.add(new TestCase("b/30458218", "B30458218", "run", null, null, null));
        testCases.add(new TestCase("b/31313170", "B31313170", "run", null, null, 0));
        testCases.add(new TestCase("ConstClassAliasing", "ConstClassAliasing", "run", null, null,
                null, true));
        testCases.add(new TestCase("b/121191566", "B121191566", "run", new Object[] { "a" }, null,
                true, false));
        testCases.add(new TestCase("b/122501785", "B122501785", "run", null, new VerifyError(),
                0));
        testCases.add(new TestCase("b/134061982", "B134061982", "run", new Object[] { 0 },
                new NullPointerException(), 0));
        testCases.add(new TestCase("b/134061982 (2)", "B134061982_2", "run", new Object[] { 0 },
                new VerifyError(), 0));
        testCases.add(new TestCase("b/121245951", "B121245951", "run", new Object[] { true,
                new Object() }, new IllegalMonitorStateException(), 0));
        testCases.add(new TestCase("b/121245951 (2)", "B121245951_2", "run", new Object[] { true,
                new Object() }, new VerifyError(), 0));
        testCases.add(new TestCase("b/121245951 (3)", "B121245951_3", "run", new Object[] {
                new Object() }, new IllegalMonitorStateException(), 0));
    }

    public void runTests() {
        for (TestCase tc : testCases) {
            System.out.println(tc.testName);
            try {
                runTest(tc);
            } catch (Exception exc) {
                exc.printStackTrace(System.out);
            }
        }
    }

    private void runTest(TestCase tc) throws Exception {
        Exception errorReturn = null;
        try {
            Class<?> c = Class.forName(tc.testClass);

            Method[] methods = c.getDeclaredMethods();

            // For simplicity we assume that test methods are not overloaded. So searching by name
            // will give us the method we need to run.
            Method method = null;
            for (Method m : methods) {
                if (m.getName().equals(tc.testMethodName)) {
                    method = m;
                    break;
                }
            }

            if (method == null) {
                errorReturn = new IllegalArgumentException("Could not find test method " +
                                                           tc.testMethodName + " in class " +
                                                           tc.testClass + " for test " +
                                                           tc.testName);
            } else {
                Object retValue;
                if (Modifier.isStatic(method.getModifiers())) {
                    retValue = method.invoke(null, tc.values);
                } else {
                    retValue = method.invoke(method.getDeclaringClass().newInstance(), tc.values);
                }
                if (tc.expectedException != null) {
                    errorReturn = new IllegalStateException("Expected an exception in test " +
                                                            tc.testName);
                } else if (tc.expectedReturn == null && retValue != null) {
                    errorReturn = new IllegalStateException("Expected a null result in test " +
                                                            tc.testName + " got " + retValue);
                } else if (tc.expectedReturn != null &&
                           (retValue == null || !tc.expectedReturn.equals(retValue))) {
                    errorReturn = new IllegalStateException("Expected return " +
                                                            tc.expectedReturn +
                                                            ", but got " + retValue);
                } else if (tc.checkCompiled && compiledWithOptimizing() && !isAotVerified(c)) {
                    errorReturn = new IllegalStateException("Expected method " + method.getName() +
                            " of class " + c.getName() +
                            " be verified in compile-time in test " + tc.testName);
                } else {
                    // Expected result, do nothing.
                }
            }
        } catch (Throwable exc) {
            if (tc.expectedException == null) {
                errorReturn = new IllegalStateException("Did not expect exception", exc);
            } else if (exc instanceof InvocationTargetException && exc.getCause() != null &&
                       exc.getCause().getClass().equals(tc.expectedException.getClass())) {
                // Expected exception is wrapped in InvocationTargetException.
            } else if (!tc.expectedException.getClass().equals(exc.getClass())) {
                errorReturn = new IllegalStateException("Expected " +
                                                        tc.expectedException.getClass().getName() +
                                                        ", but got " + exc.getClass(), exc);
            } else {
                // Expected exception, do nothing.
            }
        } finally {
            if (errorReturn != null) {
                throw errorReturn;
            }
        }
    }

    public static void main(String[] args) throws Exception {
        System.loadLibrary(args[0]);

        Main main = new Main();

        main.runTests();

        System.out.println("Done!");
    }

    private native static boolean isAotVerified(Class<?> cls);
    private native static boolean compiledWithOptimizing();
}
