package org.commonmark.test;

import org.junit.FixMethodOrder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.Stopwatch;
import org.junit.rules.Timeout;
import org.junit.runner.Description;
import org.junit.runners.MethodSorters;

import java.util.concurrent.TimeUnit;

/**
 * Pathological input cases (from commonmark.js).
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PathologicalTest extends CoreRenderingTestCase {

    private static final int X = 10_000;

    @Rule
    public Timeout timeout = new Timeout(2, TimeUnit.SECONDS);

    @Rule
    public Stopwatch stopwatch = new Stopwatch() {
        @Override
        protected void finished(long nanos, Description description) {
            System.err.println(description.getDisplayName() + " took " + (nanos / 1000000) + " ms");
        }
    };

    @Test
    public void nestedStrongEmphasis() {
        // this is limited by the stack size because visitor is recursive
        int x = 1000;
        assertRendering(
                repeat("*a **a ", x) + "b" + repeat(" a** a*", x),
                "<p>" + repeat("<em>a <strong>a ", x) + "b" +
                        repeat(" a</strong> a</em>", x) + "</p>\n");
    }

    @Test
    public void emphasisClosersWithNoOpeners() {
        assertRendering(
                repeat("a_ ", X),
                "<p>" + repeat("a_ ", X - 1) + "a_</p>\n");
    }

    @Test
    public void emphasisOpenersWithNoClosers() {
        assertRendering(
                repeat("_a ", X),
                "<p>" + repeat("_a ", X - 1) + "_a</p>\n");
    }

    @Test
    public void linkClosersWithNoOpeners() {
        assertRendering(
                repeat("a] ", X),
                "<p>" + repeat("a] ", X - 1) + "a]</p>\n");
    }

    @Test
    public void linkOpenersWithNoClosers() {
        assertRendering(
                repeat("[a ", X),
                "<p>" + repeat("[a ", X - 1) + "[a</p>\n");
    }

    @Test
    public void linkOpenersAndEmphasisClosers() {
        assertRendering(
                repeat("[ a_ ", X),
                "<p>" + repeat("[ a_ ", X - 1) + "[ a_</p>\n");
    }

    @Test
    public void mismatchedOpenersAndClosers() {
        assertRendering(
                repeat("*a_ ", X),
                "<p>" + repeat("*a_ ", X - 1) + "*a_</p>\n");
    }

    @Test
    public void nestedBrackets() {
        assertRendering(
                repeat("[", X) + "a" + repeat("]", X),
                "<p>" + repeat("[", X) + "a" + repeat("]", X) + "</p>\n");
    }

    @Test
    public void nestedBlockQuotes() {
        // this is limited by the stack size because visitor is recursive
        int x = 1000;
        assertRendering(
                repeat("> ", x) + "a\n",
                repeat("<blockquote>\n", x) + "<p>a</p>\n" +
                        repeat("</blockquote>\n", x));
    }

    private static String repeat(String s, int count) {
        StringBuilder sb = new StringBuilder(s.length() * count);
        for (int i = 0; i < count; i++) {
            sb.append(s);
        }
        return sb.toString();
    }

}

@@ -468,26 +468,13 @@
 ate 
-static final 
 int 
-X
+x
  = 1
@@ -536,9 +536,9 @@
 out(
-2
+3
 , Ti
@@ -949,36 +949,32 @@
 cursive%0A        
-int 
 x = 1000;%0A      
@@ -1307,25 +1307,25 @@
 peat(%22a_ %22, 
-X
+x
 ),%0A         
@@ -1349,25 +1349,25 @@
 peat(%22a_ %22, 
-X
+x
  - 1) + %22a_%3C
@@ -1492,25 +1492,25 @@
 peat(%22_a %22, 
-X
+x
 ),%0A         
@@ -1534,25 +1534,25 @@
 peat(%22_a %22, 
-X
+x
  - 1) + %22_a%3C
@@ -1673,25 +1673,25 @@
 peat(%22a%5D %22, 
-X
+x
 ),%0A         
@@ -1715,25 +1715,25 @@
 peat(%22a%5D %22, 
-X
+x
  - 1) + %22a%5D%3C
@@ -1854,25 +1854,25 @@
 peat(%22%5Ba %22, 
-X
+x
 ),%0A         
@@ -1896,25 +1896,25 @@
 peat(%22%5Ba %22, 
-X
+x
  - 1) + %22%5Ba%3C
@@ -2042,25 +2042,25 @@
 at(%22%5B a_ %22, 
-X
+x
 ),%0A         
@@ -2086,25 +2086,25 @@
 at(%22%5B a_ %22, 
-X
+x
  - 1) + %22%5B a
@@ -2235,17 +2235,17 @@
 %22*a_ %22, 
-X
+x
 ),%0A     
@@ -2278,17 +2278,17 @@
 %22*a_ %22, 
-X
+x
  - 1) + 
@@ -2398,33 +2398,33 @@
     repeat(%22%5B%22, 
-X
+x
 ) + %22a%22 + repeat
@@ -2429,17 +2429,17 @@
 at(%22%5D%22, 
-X
+x
 ),%0A     
@@ -2469,17 +2469,17 @@
 at(%22%5B%22, 
-X
+x
 ) + %22a%22 
@@ -2496,9 +2496,9 @@
 %5D%22, 
-X
+x
 ) + 
@@ -2645,20 +2645,16 @@
         
-int 
 x = 1000
@@ -3080,11 +3080,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Tweak timeout in PathologicalTest