/*
 * Copyright (C) 2010 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;

/*
 * Entry point and tests that are expected to succeed.
 */
public class Main {
    /**
     * Drives tests.
     */
    public static void main(String[] args) {
        System.loadLibrary(args[0]);
        if (!hasOatFile() || runtimeIsSoftFail() || isInterpreted()) {
            // Some tests ensure that the verifier was able to guarantee balanced locking by
            // asserting that the test function is running as compiled code. But skip this now,
            // as this seems to be a non-compiled code test configuration.
            disableStackFrameAsserts();
        }

        Main m = new Main();

        m.recursiveSync(0);

        m.nestedMayThrow(false);
        try {
            m.nestedMayThrow(true);
            System.err.println("nestedThrow(true) did not throw");
        } catch (MyException me) {}
        System.out.println("nestedMayThrow ok");

        m.constantLock();
        System.out.println("constantLock ok");

        m.notExcessiveNesting();

        m.notNested();
        System.out.println("notNested ok");

        Object obj1 = new Object();
        Object obj2 = new Object();

        TwoPath.twoPath(obj1, obj2, 0);
        System.out.println("twoPath ok");

        m.triplet(obj1, obj2, 0);
        System.out.println("triplet ok");

        runSmaliTests();
    }

    /**
     * Recursive synchronized method.
     */
    synchronized void recursiveSync(int iter) {
        assertIsManaged();
        if (iter < 40) {
            recursiveSync(iter+1);
        } else {
            System.out.println("recursiveSync ok");
        }
    }

    /**
     * Tests simple nesting, with and without a throw.
     */
    void nestedMayThrow(boolean doThrow) {
        assertIsManaged();
        synchronized (this) {
            synchronized (Main.class) {
                synchronized (new Object()) {
                    synchronized(Class.class) {
                        if (doThrow) {
                            throw new MyException();
                        }
                    }
                }
            }
        }
    }

    /**
     * Exercises bug 3215458.
     */
    void constantLock() {
        assertIsManaged();
        Class<?> thing = Thread.class;
        synchronized (Thread.class) {}
    }

    /**
     * Confirms that we can have 32 nested monitors on one method.
     */
    void notExcessiveNesting() {
        assertIsManaged();
        synchronized (this) {   // 1
        synchronized (this) {   // 2
        synchronized (this) {   // 3
        synchronized (this) {   // 4
        synchronized (this) {   // 5
        synchronized (this) {   // 6
        synchronized (this) {   // 7
        synchronized (this) {   // 8
        synchronized (this) {   // 9
        synchronized (this) {   // 10
        synchronized (this) {   // 11
        synchronized (this) {   // 12
        synchronized (this) {   // 13
        synchronized (this) {   // 14
        synchronized (this) {   // 15
        synchronized (this) {   // 16
        synchronized (this) {   // 17
        synchronized (this) {   // 18
        synchronized (this) {   // 19
        synchronized (this) {   // 20
        synchronized (this) {   // 21
        synchronized (this) {   // 22
        synchronized (this) {   // 23
        synchronized (this) {   // 24
        synchronized (this) {   // 25
        synchronized (this) {   // 26
        synchronized (this) {   // 27
        synchronized (this) {   // 28
        synchronized (this) {   // 29
        synchronized (this) {   // 30
        synchronized (this) {   // 31
        synchronized (this) {   // 32
        }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
    }

    /**
     * Confirms that we can have more than 32 non-nested monitors in one
     * method.
     */
    void notNested() {
        assertIsManaged();
        synchronized (this) {}  // 1
        synchronized (this) {}  // 2
        synchronized (this) {}  // 3
        synchronized (this) {}  // 4
        synchronized (this) {}  // 5
        synchronized (this) {}  // 6
        synchronized (this) {}  // 7
        synchronized (this) {}  // 8
        synchronized (this) {}  // 9
        synchronized (this) {}  // 10
        synchronized (this) {}  // 11
        synchronized (this) {}  // 12
        synchronized (this) {}  // 13
        synchronized (this) {}  // 14
        synchronized (this) {}  // 15
        synchronized (this) {}  // 16
        synchronized (this) {}  // 17
        synchronized (this) {}  // 18
        synchronized (this) {}  // 19
        synchronized (this) {}  // 20
        synchronized (this) {}  // 21
        synchronized (this) {}  // 22
        synchronized (this) {}  // 23
        synchronized (this) {}  // 24
        synchronized (this) {}  // 25
        synchronized (this) {}  // 26
        synchronized (this) {}  // 27
        synchronized (this) {}  // 28
        synchronized (this) {}  // 29
        synchronized (this) {}  // 30
        synchronized (this) {}  // 31
        synchronized (this) {}  // 32
        synchronized (this) {}  // 33
        synchronized (this) {}  // 34
    }

    /* does nothing but ensure that the compiler doesn't discard an object */
    private void doNothing(Object obj) {}

    /**
     * Lock the monitor two or three times, and make use of the locked or
     * unlocked object.
     */
    public void triplet(Object obj1, Object obj2, int x) {
        Object localObj;

        synchronized (obj1) {
            synchronized(obj1) {
                if (x == 0) {
                    synchronized(obj1) {
                        localObj = obj2;
                    }
                } else {
                    localObj = obj1;
                }
            }
        }

        doNothing(localObj);
    }

    // Smali testing code.
    private static void runSmaliTests() {
        runTest("OK", new Object[] { new Object(), new Object() }, null);
        runTest("TooDeep", new Object[] { new Object() }, null);
        runTest("NotStructuredOverUnlock", new Object[] { new Object() },
                IllegalMonitorStateException.class);
        runTest("NotStructuredUnderUnlock", new Object[] { new Object() },
                IllegalMonitorStateException.class);
        runTest("UnbalancedJoin", new Object[] { new Object(), new Object() }, null);
        runTest("UnbalancedStraight", new Object[] { new Object(), new Object() }, null);
        runTest("NullLocks", new Object[] { false }, null);
        runTest("NullLocks", new Object[] { true }, NullPointerException.class);
    }

    private static void runTest(String className, Object[] parameters, Class<?> excType) {
        try {
            Class<?> c = Class.forName(className);

            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("run")) {
                    method = m;
                    break;
                }
            }

            if (method == null) {
                System.out.println("Could not find test method for " + className);
            } else if (!Modifier.isStatic(method.getModifiers())) {
                System.out.println("Test method for " + className + " is not static.");
            } else {
                method.invoke(null, parameters);
                if (excType != null) {
                    System.out.println("Expected an exception in " + className);
                }
            }
        } catch (Throwable exc) {
            if (excType == null) {
                System.out.println("Did not expect exception " + exc + " for " + className);
                exc.printStackTrace(System.out);
            } else if (exc instanceof InvocationTargetException && exc.getCause() != null &&
                       exc.getCause().getClass().equals(excType)) {
                // Expected exception is wrapped in InvocationTargetException.
            } else if (!excType.equals(exc.getClass())) {
                System.out.println("Expected " + excType.getName() + ", but got " + exc.getClass());
            } else {
              // Expected exception, do nothing.
            }
        }
    }

    // Helpers for the smali code.
    public static native void assertIsInterpreted();
    public static native void assertIsManaged();
    public static native boolean hasOatFile();
    public static native boolean runtimeIsSoftFail();
    public static native boolean isInterpreted();
    public static native void disableStackFrameAsserts();
}
