package org.webdsl.tools;


import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.safety.Whitelist;
import org.pegdown.LinkRenderer;
import org.pegdown.PegDownProcessor;
import org.webdsl.logging.Logger;

import utils.AbstractPageServlet;


public final class WikiFormatter {
	
    private static final Pattern verbatim = Pattern.compile("<verbatim>(.+?)</verbatim>", Pattern.DOTALL | Pattern.MULTILINE);
    private static String currentRootUrl = "";
    private static LinkRenderer currentLinkRenderer = null;
    private static final Whitelist whitelist = org.jsoup.safety.Whitelist.relaxed();
    public static final int PARSE_TIMEOUT_MS = 6000;
    
	static{
		whitelist.addTags("abbr").addAttributes("abbr", "title");
		//allow id's on title tags
		for(int i=1;i<7;i++){
			whitelist.addAttributes("h"+i, "id");
		}
	}

    public static String wikiFormat(String text) {
    	AbstractPageServlet threadLocalPage = utils.ThreadLocalPage.get();
    	return org.jsoup.Jsoup.clean( wikiFormat( text, threadLocalPage.getPegDownProcessor(), threadLocalPage.getAbsoluteLocation()+utils.ThreadLocalServlet.getContextPath() ), whitelist );
    }
    
    //Similar to wikiFormat( text ) , but without cleaning by JSoup
    public static String wikiFormatNoTagFiltering(String text) {
    	AbstractPageServlet threadLocalPage = utils.ThreadLocalPage.get();
    	return wikiFormat( text, threadLocalPage.getPegDownProcessor(), threadLocalPage.getAbsoluteLocation()+utils.ThreadLocalServlet.getContextPath() );
    }
    
    public static String wikiFormat(String text, PegDownProcessor processor, String rootUrl){
    	String html;
    	try {
    		html = processor.markdownToHtml( processVerbatim(text), getLinkRenderer( rootUrl ) );
    	} catch (Exception e) {
			Logger.error(e);
			html = null;
		}
    	return html == null ? errorMessage(text) : html;
    }    
    
    private static String errorMessage( String text ){
    	StringBuilder sb = new StringBuilder(text.length() + 128);
    	sb.append("Something went wrong processing the following markdown text (parsing automatically stopped after ")
    	  .append(PARSE_TIMEOUT_MS)
    	  .append("ms): ")
    	  .append("<pre>")
    	  .append(text)
    	  .append("</pre>");
    	return sb.toString();
    }

    private static String processVerbatim(String text) {
        Matcher m = verbatim.matcher(text);
        if (m.find()){
        	StringBuffer sb = new StringBuffer( text.length() + 256 );
        	do {
        		String newText = "\n        " +
                        m.group(1).replaceAll("\n", "\n        ")
                                  .replaceAll("\\\\", "\\\\\\\\")
                                  .replaceAll("\\$", "\\\\\\$") +
                        "\n";
                m.appendReplacement(sb, newText);
        		
        	} while (m.find());
        	m.appendTail(sb);
        	return sb.toString();
        } else {
        	return text;
        }
    }
    
    private static synchronized LinkRenderer getLinkRenderer( String rootUrl ){
    	if(!currentRootUrl.equals(rootUrl) && rootUrl != null ) {
			currentRootUrl = rootUrl;
			currentLinkRenderer = new WebDSLLinkRenderer(rootUrl);
		}
    	return currentLinkRenderer;
    }

//    public static void main(String[] args) {
//        System.out.println("The output:");
//        System.out
//                .println(wikiFormat("This is a header\n=========\n\nAnd here's a link [[page(MainPage)|Main page]].\nHello people! [[home()]] -- [[home|Terug naar de homepage]]\n\nHere is some verbatim:\n<verbatim>Dit is een test <hoi>. Enzovoorts\nBlabla\n\n  Free $$$ for all!</verbatim>Doei.", "/test"));
//    }
    

}
@@ -711,17 +711,35 @@
 s(%22abbr%22
-)
+, %22hr%22)%0A%09%09         
 .addAttr
@@ -761,16 +761,98 @@
 %22title%22)
+%0A%09%09         .addAttributes(%22th%22, %22align%22)%0A%09%09         .addAttributes(%22td%22, %22align%22)
 ;%0A%09%09//al
@@ -1735,26 +1735,8 @@
 l)%7B%0A
-    %09String html;%0A
     
@@ -1748,22 +1748,22 @@
 %7B%0A    %09%09
-html =
+return
  process
@@ -1890,51 +1890,14 @@
 %0A%09%09%09
-html = null;%0A%09%09%7D%0A    %09return html == null ?
+return
  err
@@ -1915,16 +1915,13 @@
 ext)
- : html;
+;%0A%09%09%7D
 %0A   

Allow horizontal rule and table alignment in markdown