package com.jobst_software.markdown2any;



import com.jobst_software.gjc2sx.Initable;
import com.jobst_software.gjc2sx.helpers.Ut;

import com.jobst_software.gjc2sx.Disposable;
import com.jobst_software.gjc2sx.HasROClientProperties;
import com.jobst_software.gjc2sx.PrintableGj;

import java.util.Vector;
import java.util.Collections;
import java.util.Comparator;




public class  MarkdownDocument   implements Initable, Disposable {
	
		public static class  MarkdownIssue {
			public static String    ISSUE_ID 			= "id";
			public static int       ISSUE_ID_FD_NO 		= 0;
			
			public static String  	SUBJECT 			= "subject";
			public static int  	    SUBJECT_FD_NO 		= 1;
			
			public static String  	DESCRIPTION 		= "description";
			public static int     	DESCRIPTION_FD_NO 	= 2;
			
			public static String[]  FD_NAMES  = new  String[] { ISSUE_ID, SUBJECT, DESCRIPTION };

			
			// mems
			//
			public Vector<String>  headers  	= new  Vector<String>();
			public String          tracker_name = "";
			public Object[]  	   fdValues 	= new  Object[ FD_NAMES.length];

			
			public String  format( boolean withHeaders, boolean withSort, boolean withIssueId, boolean formatted) {
				return    ( withSort   
								? ("0" + headers.size())  
								: "" )	
						+ ( withHeaders 
								? Ut.formatArray( headers.toArray(  new String[ headers.size()]), " / ") + " "
								: "")
						+ format( tracker_name, "**", "**", formatted)
						+ " - "
						
						+ ( withIssueId   
								? format( fdValues[ MarkdownIssue.ISSUE_ID_FD_NO], "*#", "* ", formatted)
								: "" )
						+ ( fdValues.length == 0 
								? "" 
								: format( fdValues[ SUBJECT_FD_NO], "**", "**", formatted));
			}
			
			
			public static String  format( Object t, String start, String end, boolean formatted) {
				return    ( formatted ? start : "" ) 
						+ Ut.makeString( t) 
						+ ( formatted ? end : "" ); 
			}
		}

		
		public class  MarkdownIssueComparator   implements Comparator<MarkdownIssue> {
			
			@Override
			public int 	compare(MarkdownIssue v1,                           MarkdownIssue v2) {
				return  v1.format(true /* withHeaders */, true /* withSort */, false /* withIssueId */, false /* formatted */).compareTo( 
						v2.format(true /* withHeaders */, true /* withSort */, false /* withIssueId */, false /* formatted */));
			}
			
		}		
		
	
		

	
	// refs
	//
	protected String[] 			 main_args;
	protected MarkdownSqlSource  sqlSource;
	
		
	// mems
	// 
	protected Vector<MarkdownIssue>  issues = null;
	
	
	
public  MarkdownDocument( String[] main_args)   throws Exception
{
	this.main_args = main_args;
}	
	
	
@Override
public void init() throws Exception {
	issues = new Vector<MarkdownIssue>();
}



@Override
public void  dispose() {
	issues = null;
}
	

protected MarkdownIssue  createMarkdownIssue() {
	return                new  MarkdownIssue();
}

	
public void  add( Vector<String> headers, String tracker_name, HasROClientProperties src_row)   throws Exception {
	MarkdownIssue  issue = createMarkdownIssue();
	issues.add(    issue);
	
	issue.headers 		= headers;
	issue.tracker_name 	= tracker_name;
	
	for(            int f_i=0;                      f_i < MarkdownIssue.FD_NAMES.length;  f_i++ ) {
		issue.fdValues[ f_i] = src_row.getClientProperty( MarkdownIssue.FD_NAMES[ 		  f_i]);
	}
}


public void  writeTo( PrintableGj out, MarkdownSqlSource sqlSource)   throws Exception {
	this.sqlSource 									   = sqlSource;
	
	Collections.sort( 		   issues, new MarkdownIssueComparator());
	
	Vector<String>  prev_headers = null;
	
	for( int i_i=0;      i_i < issues.size();   i_i++ ) {
		MarkdownIssue  issue = issues.get(      i_i);

		String   				   HEADER_SIGNS = "########################################";
		for(    int h_i=0;   h_i < HEADER_SIGNS.length()  &&  h_i < issue.headers.size();   h_i++ ) {
			String  header 					      =  Ut.makeString( issue.headers.get(      h_i));
			
			if( 		prev_headers == null  
					||  h_i >= prev_headers.size() 
					||  !Ut.makeString(prev_headers.get(h_i)).equals(header)   ) {
				out.print(   		HEADER_SIGNS.substring( 0, 1 + h_i));
				out.print(   		"\u0020");
				out.print(   		header);
				out.println("");
				out.println("");
			}
		}
		
		// int 								  			        P_HEADER_STARTLEVEL = 5;
		// String     p_header_prefix = HEADER_SIGNS.substring( 0, P_HEADER_STARTLEVEL);
		// out.print( p_header_prefix);
		// out.print( "\u0020");

		out.println( "");
		out.println( "---");
		out.println( "");
		
		outSubject( 	out, issue);
		outDescription( out, issue);
		
		
		prev_headers = issue.headers;
	}
}


protected void  outSubject( PrintableGj out, MarkdownIssue issue) throws Exception {
	out.print(   issue.format( false /* withHeaders */, false/* withSort */, true /* withIssueId */, true /* formatted */));
	
//	String             issue_id_asText = Ut.makeString( issue.fdValues[ MarkdownIssue.ISSUE_ID_FD_NO]);
//	if( 	!"".equals(issue_id_asText) ) {
//		out.print(   " *#");
//		out.print(   issue_id_asText);
//		out.print( 	 "*");
//	}
	
	out.println( "");
	out.println( "");
}


protected void  outDescription( PrintableGj out, MarkdownIssue issue) throws Exception {
	
	String  text = Ut.makeString( issue.fdValues[ MarkdownIssue.DESCRIPTION_FD_NO]);
	
	String[]  			      		           lines = Ut.scanArray( Ut.makeString( text), nl(), false);
	for(   int l_i=0;   		         l_i < lines.length;   l_i++ ) {
		outDescriptionLine(  out, 			   lines[ 		   l_i]);
	}
	
	out.println( "");
	out.println( "");
}




/**
 * textline	"- [Dokumentation (aktiv)](/issues?query_id=33)" 
 * 			   012345678901234567890123456789012345678901234
 *                       1         2         3         4
 */

protected void  outDescriptionLine( PrintableGj out, String textline)   throws Exception {
	String  res = Ut.makeString(                            textline);

	int  	startPos = res.indexOf("[");
	String  					    								     			  LINK_START = "](";
	String  					    								 REL_LINK_START = LINK_START + "/";
	int  							     linkStartPos = res.indexOf( REL_LINK_START);
	int  														                   linkEndPos = res.indexOf(")", linkStartPos);
	if( 	startPos >= 0       &&  startPos < linkStartPos     &&  linkStartPos < linkEndPos ) {
		String  href          = res.substring( linkStartPos + LINK_START.length(), linkEndPos);
		int  	imgStartPos = res.indexOf("![");
		if(  	imgStartPos >= 0  &&  imgStartPos == (startPos - 1) ) {
			href = sqlSource.adjustImgHref( 							   href);
			res  = res.substring( 0, linkStartPos + LINK_START.length()) + href + res.substring( linkEndPos);
		} 
		else {
			href = sqlSource.adjustLinkHref( 						   	   href);
			res  = res.substring( 0, linkStartPos + LINK_START.length()) + href + res.substring( linkEndPos);
		}
	}
	out.println( res);
}






protected String  nl() {
	return  System.getProperty("line.separator");
}





}
