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


/*
 * Entry point and tests that are expected to succeed.
 */
public class Main {
    /**
     * Drives tests.
     */
    public static void main(String[] args) {
        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();
        try {
            TooDeep.excessiveNesting();
            System.err.println("excessiveNesting did not throw");
        } catch (VerifyError ve) {}
        System.out.println("excessiveNesting ok");

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

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

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

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

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

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

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

    /**
     * Confirms that we can have 32 nested monitors on one method.
     */
    void notExcessiveNesting() {
        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() {
        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) {}

    /**
     * Conditionally uses one of the synchronized objects.
     */
    public void twoPath(Object obj1, Object obj2, int x) {
        Object localObj;

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

        doNothing(localObj);
    }

    /**
     * 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);
    }
}
