package org.jdesktop.swinghelper.debug;

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

final class Tests {

  public static void main(String[] args) {
    if (args.length == 0) {
      return;
    }
    String mode = args[0];

    new EventDispatchThreadHangMonitor().initMonitoring();

    if ("deadlock".equals(mode)) {
      runDeadlockTest();
      return;
    }

    EventQueue.invokeLater(
        () -> {
          final JFrame frame = new JFrame();
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setLocationRelativeTo(null);
          switch (mode) {
            case "exception":
              runExceptionTest(frame);
              break;
            case "focus":
              runFocusTest(frame);
              break;
            case "modal-hang":
              runModalTest(frame, true);
              break;
            case "modal-no-hang":
              runModalTest(frame, false);
              break;
            default:
              System.err.println("unknown regression test '" + mode + "'");
              System.exit(1);
          }
          frame.pack();
          frame.setVisible(true);
        });
  }

  public static void runDeadlockTest() {
    class Locker {

      private Locker locker;

      public void setLocker(Locker locker) {
        this.locker = locker;
      }

      public synchronized void tryToDeadlock() {
        String unused = locker.toString();
      }

      @Override
      @SuppressWarnings("CatchAndPrintStackTrace")
      public synchronized String toString() {
        try {
          Thread.sleep(50);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        return super.toString();
      }
    }

    final Locker one = new Locker();
    final Locker two = new Locker();
    one.setLocker(two);
    two.setLocker(one);

    // Deadlock expected here:
    for (int i = 0; i < 100; i++) {
      SwingUtilities.invokeLater(one::tryToDeadlock);
      two.tryToDeadlock();
    }
  }

  // If we don't do our post-dispatch activity in a finally block, we'll
  // report bogus hangs.
  private static void runExceptionTest(final JFrame frame) {
    JButton button = new JButton("Throw Exception");
    button.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            // This shouldn't cause us to report a hang.
            throw new IllegalStateException("Nobody expects the Spanish Inquisition!");
          }
        });
    frame.add(button);
  }

  // A demonstration of nested calls to dispatchEvent caused by SequencedEvent.
  private static void runFocusTest(final JFrame frame) {
    final JDialog dialog = new JDialog(frame, "Non-Modal Dialog");
    dialog.add(new JLabel("Close me!"));
    dialog.pack();
    dialog.setLocationRelativeTo(frame);
    dialog.addWindowFocusListener(
        new WindowAdapter() {
          @Override
          public void windowGainedFocus(WindowEvent e) {
            System.out.println("FocusTest.windowGainedFocus");
            // If you don't cope with nested calls to dispatchEvent, you won't detect this.
            // See java.awt.SequencedEvent for an example.
            sleep(2500);
          }
        });
    JButton button = new JButton("Show Non-Modal Dialog");
    button.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            dialog.setVisible(true);
          }
        });
    frame.add(button);
  }

  // A demonstration of the problems of dealing with modal dialogs.
  private static void runModalTest(final JFrame frame, final boolean shouldSleep) {
    System.out.println(shouldSleep ? "Expect hangs!" : "There should be no hangs...");
    JButton button = new JButton("Show Modal Dialog");
    button.addActionListener(
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            if (shouldSleep) {
              sleep(2500); // This is easy.
            }
            JDialog dialog = new JDialog(frame, "Modal dialog", /* modal= */ true);
            dialog.setLayout(new FlowLayout());
            dialog.add(new JLabel("Close this dialog!"));
            final JLabel label = new JLabel(" ");
            dialog.add(label);
            dialog.pack();
            dialog.setLocation(frame.getX() - 100, frame.getY());

            // Make sure the new event pump has some work to do, each unit of which is insufficient
            // to cause a hang.
            new Thread(
                () -> {
                  for (int i = 0; i <= 100000; ++i) {
                    final int value = i;
                    EventQueue.invokeLater(() -> label.setText(Integer.toString(value)));
                  }
                })
                .start();

            dialog.setVisible(true);

            if (shouldSleep) {
              sleep(
                  2500); // If you don't distinguish different stack traces, you won't report this.
            }
          }
        });
    frame.add(button);
  }

  @SuppressWarnings("CatchAndPrintStackTrace")
  private static void sleep(long ms) {
    try {
      System.out.println("Sleeping for " + ms + " ms on " + Thread.currentThread() + "...");
      Thread.sleep(ms);
      System.out.println("Finished sleeping...");
    } catch (InterruptedException ex) {
      ex.printStackTrace();
    }
  }

  private Tests() {
  }
}