/*
 * Copyright (C) 2006 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.
 */

/**
 * Test synchronization primitives.
 *
 * TODO: this should be re-written to be a little more rigorous and/or
 * useful.  Also, the ThreadDeathHandler stuff should be exposed or
 * split out.
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("Sleep Test");
        sleepTest();

        System.out.println("\nCount Test");
        countTest();

        System.out.println("\nInterrupt Test");
        interruptTest();
    }

    static void sleepTest() {
        System.out.println("GOING");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ie) {
            System.out.println("INTERRUPT!");
            ie.printStackTrace();
        }
        System.out.println("GONE");
    }

    static void countTest() {
        CpuThread one, two;

        one = new CpuThread(1);
        two = new CpuThread(2);

        synchronized (one) {
            one.start();
            try {
                one.wait();
            } catch (InterruptedException ie) {
                System.out.println("INTERRUPT!");
                ie.printStackTrace();
            }
        }

        two.start();

        //System.out.println("main: off and running");

        try {
            one.join();
            two.join();
        } catch (InterruptedException ie) {
            System.out.println("INTERRUPT!");
            ie.printStackTrace();
        }
        System.out.println("main: all done");
    }

    static void interruptTest() {
        SleepyThread sleepy, pesky;

        sleepy = new SleepyThread(null);
        pesky = new SleepyThread(sleepy);

        sleepy.setPriority(4);
        sleepy.start();
        pesky.start();
        pesky.setPriority(3);
    }
}

class CpuThread extends Thread {
    static Object mSyncable = new Object();
    static int mCount = 0;
    int mNumber;

    CpuThread(int num) {
        super("CpuThread " + num);
        mNumber = num;
    }

    public void run() {
        //System.out.print("thread running -- ");
        //System.out.println(Thread.currentThread().getName());

        synchronized (mSyncable) {
            synchronized (this) {
                this.notify();
            }
            for (int i = 0; i < 10; i++) {
                output(mNumber);
            }

            System.out.print("Final result: ");
            System.out.println(mCount);
        }
    }

    void output(int num) {
        int count = mCount;

        System.out.print("going: ");
        System.out.println(num);

        /* burn CPU; adjust end value so we exceed scheduler quantum */
        for (int j = 0; j < 5000; j++) {
            ;
        }

        count++;
        mCount = count;
    }
}

class SleepyThread extends Thread {
    private SleepyThread mOther;
    private Integer[] mWaitOnMe;      // any type of object will do

    private static int count = 0;

    SleepyThread(SleepyThread other) {
        mOther = other;
        mWaitOnMe = new Integer[] { 1, 2 };

        setName("thread#" + count);
        count++;
    }

    public void run() {
        System.out.println("SleepyThread.run starting");

        if (false) {
            ThreadDeathHandler threadHandler =
                new ThreadDeathHandler("SYNC THREAD");
            Thread.currentThread().setUncaughtExceptionHandler(threadHandler);
            throw new NullPointerException("die");
        }

        if (mOther == null) {
            boolean intr = false;

            try {
                synchronized (mWaitOnMe) {
                    mWaitOnMe.wait(9000);
                }
            } catch (InterruptedException ie) {
                // Expecting this; interrupted should be false.
                System.out.println(Thread.currentThread().getName() +
                        " interrupted, flag=" + Thread.interrupted());
                intr = true;
            } catch (Exception ex) {
                ex.printStackTrace();
            }

            if (!intr)
                System.out.println("NOT INTERRUPTED");
        } else {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ie) {
                System.out.println("PESKY INTERRUPTED?");
            }

            System.out.println("interrupting other (isAlive="
                + mOther.isAlive() + ")");
            mOther.interrupt();
        }
    }
}
