/*
 * 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.util.concurrent.Semaphore;
import java.util.Arrays;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.function.IntUnaryOperator;
import java.util.function.Function;

public class Test1924 {
  public static void handleFramePop(Executable m, boolean exception, long location) {
    System.out.println(
        m + " pop. Line=" + Breakpoint.locationToLine(m, location) + " exception:" + exception);
  }

  public static void recurTimesA(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesB(times - 1, safepoint);
  }

  public static void recurTimesB(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesC(times - 1, safepoint);
  }

  public static void recurTimesC(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesD(times - 1, safepoint);
  }

  public static void recurTimesD(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesE(times - 1, safepoint);
  }

  public static void recurTimesE(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesF(times - 1, safepoint);
  }

  public static void recurTimesF(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesG(times - 1, safepoint);
  }

  public static void recurTimesG(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesH(times - 1, safepoint);
  }

  public static void recurTimesH(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesI(times - 1, safepoint);
  }

  public static void recurTimesI(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesJ(times - 1, safepoint);
  }

  public static void recurTimesJ(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    recurTimesK(times - 1, safepoint);
  }

  public static class RecursionError extends Error {
    public RecursionError(String s) { super(s); }
  }
  public static void recurTimesK(int times, Runnable safepoint) {
    if (times == 0) {
      safepoint.run();
      return;
    }
    safepoint.run();
    throw new RecursionError("Unable recur further. Still " + times + " outstanding!");
  }

  public static class ThreadPauser implements Runnable {
    public final Semaphore sem_wakeup_main;
    public final Semaphore sem_wait;

    public ThreadPauser() {
      sem_wakeup_main = new Semaphore(0);
      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();
    }

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

  public static void doRecurTestWith(final int times, int watch_frame) throws Exception {
    final String target_method_name_start = "recurTimes";
    final ThreadPauser safepoint = new ThreadPauser();
    Thread target = new Thread(null,
        () -> {
          try {
            recurTimesA(times, safepoint);
            System.out.println("Ran recurTimes(" + times + ") without errors!");
          } catch (RecursionError e) {
            System.out.println("Caught exception " + e + " while running recurTimes(" + times + ")");
          }
        },
        "RecurTimes(" + times + ") watching: " + watch_frame + " runner.",
        // 4000 kb stack since ASAN can make us stack-overflow otherwise
        4000 * 1024);
    target.start();
    safepoint.waitForOtherThreadToPause();
    Suspension.suspend(target);
    // Safe block
    int cnt = 0;
    StackTrace.StackFrameData target_frame = null;
    for (StackTrace.StackFrameData frame : StackTrace.GetStackTrace(target)) {
      if (frame.method.getName().startsWith(target_method_name_start)) {
        if (times - cnt == watch_frame) {
          target_frame = frame;
          break;
        } else {
          cnt++;
        }
      }
    }
    if (target_frame != null) {
      FramePop.notifyFramePop(target, target_frame.depth);
    } else {
      System.out.println(
          "Unable to find stack frame for " + watch_frame + " depth of "
          + target_method_name_start);
    }
    Suspension.resume(target);
    toggleFramePop(null);
    safepoint.wakeupOtherThread();
    target.join();
  }

  public static void run() throws Exception {
    // TODO Investigate what thread argument means for FramePop event enable.
    // Listen for events on all threads.
    FramePop.enableFramePopEvent(
        Test1924.class,
        Test1924.class.getDeclaredMethod(
            "handleFramePop", Executable.class, Boolean.TYPE, Long.TYPE),
        null);
    doRecurTestWith(10, 0);
    doRecurTestWith(10, 5);
    doRecurTestWith(10, 10);
    doRecurTestWith(100, 95);
  }

  public static native void toggleFramePop(Thread thr);
}
