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

package art;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.Vector;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.Consumer;

public class Test1917 {
    public final static boolean TEST_PRINT_ALL = false;

    public static class ThreadPauser implements Runnable {
        public Semaphore sem_wakeup_main = new Semaphore(0);
        public Semaphore sem_wait = new Semaphore(0);

        public void run() {
            try {
                sem_wakeup_main.release();
                sem_wait.acquire();
            } catch (Exception e) {
                throw new Error("Error with semaphores!", e);
            }
        }

        public void waitForOtherThreadToPause() throws Exception {
            sem_wakeup_main.acquire();
            while (!sem_wait.hasQueuedThreads()) {}
        }

        public void wakeupOtherThread() throws Exception {
            sem_wait.release();
        }
    }

    public static class StackTraceGenerator implements Runnable {
        private final Thread thr;
        private final Consumer<StackTrace.StackFrameData> con;
        public StackTraceGenerator(Thread thr, Consumer<StackTrace.StackFrameData> con) {
            this.thr = thr;
            this.con = con;
        }

        public StackTraceGenerator(Consumer<StackTrace.StackFrameData> con) {
            this(null, con);
        }

        public Thread getThread() {
            if (thr == null) {
                return Thread.currentThread();
            } else {
                return thr;
            }
        }
        public void run() {
            for (StackTrace.StackFrameData s : StackTrace.GetStackTrace(getThread())) {
                con.accept(s);
            }
        }
    }

    public static class RecurCount implements Runnable {
        private final int cnt;
        private final Runnable then;
        public RecurCount(int cnt, Runnable then) {
            this.cnt = cnt;
            this.then = then;
        }

        public void run() {
            doRecur(0);
        }

        public void doRecur(int n) {
            if (n < cnt) {
                doRecur(n + 1);
            } else {
                then.run();
            }
        }
    }

    public static Consumer<StackTrace.StackFrameData> makePrintStackFramesConsumer()
            throws Exception {
        final Method end_method = Test1917.class.getDeclaredMethod("run");
        return new Consumer<StackTrace.StackFrameData>() {
            public void accept(StackTrace.StackFrameData data) {
                if (TEST_PRINT_ALL) {
                    System.out.println(data);
                } else {
                    Package p = data.method.getDeclaringClass().getPackage();
                    // Filter out anything to do with the testing harness.
                    if (p != null && p.equals(Test1917.class.getPackage())) {
                        System.out.printf("'%s' line: %d\n",
                                data.method,
                                Breakpoint.locationToLine(data.method, data.current_location));
                    } else if (data.method.getDeclaringClass().equals(Semaphore.class)) {
                        System.out.printf("'%s' line: <NOT-DETERMINISTIC>\n", data.method);
                    }
                }
            }
        };
    }

    public static void run() throws Exception {
        System.out.println("Recurring 5 times");
        new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())).run();

        System.out.println("Recurring 5 times on another thread");
        Thread thr = new Thread(
                Thread.currentThread().getThreadGroup(),
                new RecurCount(5, new StackTraceGenerator(makePrintStackFramesConsumer())),
                "Recurring Thread 1",
                10*1000000 /* 10 mb*/);
        thr.start();
        thr.join();

        System.out.println("Recurring 5 times on another thread. Stack trace from main thread!");
        ThreadPauser pause = new ThreadPauser();
        Thread thr2 = new Thread(
                Thread.currentThread().getThreadGroup(),
                new RecurCount(5, pause),
                "Recurring Thread 2",
                10*1000000 /* 10 mb*/);
        thr2.start();
        pause.waitForOtherThreadToPause();
        new StackTraceGenerator(thr2, makePrintStackFramesConsumer()).run();
        pause.wakeupOtherThread();
        thr2.join();
    }
}
