package hiro.yoshioka.sql.util;

import hiro.yoshioka.util.StringUtil;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class CommentAnalyzer {

	protected static Log fLogger = LogFactory.getLog(CommentAnalyzer.class
			.getClass());
	static final String test = StringUtil.EMPTY_STRING
			+ " -- interceptors=sampleAddColumn.js  \n"

			+ "\n" + "\nSELECT";
	static Pattern MULTI_COMMENT = Pattern.compile("/[*](.*)?[*]/",
			Pattern.DOTALL | Pattern.MULTILINE);
	static Pattern SINGLE_COMMENT = Pattern.compile("[\\s]*--[\\s]*(.*)[\\s]*");
	static Pattern BAR_GRAPH_ON_CHART = Pattern.compile(
			"BAR_GRAPH_ON_CHART[\\s]*=[\\s]*(TRUE|FALSE)",
			Pattern.CASE_INSENSITIVE);
	static Pattern INTERCEPTORS_LINE = Pattern.compile(
			"INTERCEPTORS\\s*\\[([^]]+)\\]", Pattern.CASE_INSENSITIVE);
	static Pattern MULTI_LINE = Pattern.compile(
			"MULTI_LINE[\\s]*=[\\s]*(\\d+)", Pattern.CASE_INSENSITIVE);
	static Pattern GRAPH = Pattern.compile(
			"GRAPH_(PIE|TIME)\\s*\\[([^\\]]+)\\]", Pattern.CASE_INSENSITIVE);

	/*
	 * 0: LINK[\\s]+[\\[][\\s]*COLIDX[\\s]*= 1: ([\\d+])[\\s]+ 2: (BIND[\\s]*=
	 * 3: ([\\d, ]+))? 4: (POPUP[\\s]*=[\\s]* 5: (true|false))? 6:
	 * (HREF|SQL)[\\s]*=[\\s]* 7: ([^\\]]+)[\\]]
	 */
	static Pattern PROGRAM_LAUNCH = Pattern.compile(
			"LAUNCH\\s+IDX\\s*=([\\d]+)(\\s+(ON_?LOAD|ON_?CLICK))",
			Pattern.CASE_INSENSITIVE);

	static final CommentInfo NO_COMMENT = new CommentInfo(false);

	public static String getCommnet(String target) {
		if (StringUtil.isEmpty(target)) {
			return StringUtil.EMPTY_STRING;
		}
		Matcher m = SINGLE_COMMENT.matcher(target);
		StringBuffer buf = new StringBuffer();
		while (m.find()) {
			buf.append(m.group(1) + StringUtil.LINE_SEPARATOR);
		}
		return buf.toString();
	}

	public static CommentInfo parse(String target) {
		String parse = getCommnet(target);
		if (parse.length() == 0) {
			fLogger.trace("no comment");
			return NO_COMMENT;
		}
		CommentInfo ret = new CommentInfo(false);
		try {
			Matcher m = BAR_GRAPH_ON_CHART.matcher(parse);
			if (m.find()) {
				fLogger.trace("BAR_GRAPH_ON_CHART[" + m.group(1) + "]");
				ret.supportBarGraph = Boolean.parseBoolean(m.group(1));
				ret.supportChartResultSet = true;
			}
			m = INTERCEPTORS_LINE.matcher(parse);
			if (m.find()) {
				fLogger.trace("INTERCEPTORS[" + m.group(1) + "]");
				String[] files = m.group(1).split(",");
				for (String s : files) {
					String ss = s.trim();
					if (ss.length() > 0) {
						ret.addInterceptorComment(ss);
					}
				}
			}
			m = MULTI_LINE.matcher(parse);
			if (m.find()) {
				fLogger.trace("MULTI_LINE[" + m.group(1) + "]");
				ret.supportMultiLine = Integer.parseInt(m.group(1));
				ret.supportChartResultSet = true;
			}

			Matcher m2 = GRAPH.matcher(parse);
			while (m2.find()) {
				ret.supportChartResultSet = true;
				ret.add(m2.group(1), m2.group(2).trim());
			}

			Matcher m3 = PROGRAM_LAUNCH.matcher(parse);
			while (m3.find()) {
				if (m3.groupCount() >= 3) {
					fLogger.trace(String.format(
							"LINK index=%s lauch_timing=%s", m3.group(1),
							m3.group(3)));
					ret.addLink(Integer.parseInt(m3.group(1)),
							LaunchTimingType.parse(m3.group(3)));
				} else {
					fLogger.trace(String.format(
							"LINK index=%s lauch_timing is default",
							m3.group(1)));
					ret.addLink(Integer.parseInt(m3.group(1)), null);
				}
				ret.supportChartResultSet = true;
			}
			fLogger.trace("result=" + ret);
		} catch (Exception e) {
			fLogger.error(StringUtil.EMPTY_STRING, e);
			e.printStackTrace();
			return NO_COMMENT;
		}

		return ret;
	}

	public static void main(String[] args) {
		System.out.println(test);
		System.out.println("---------");

		// String str = "graph_time[ Biorhythm:1:2,3,4 ]";
		// Matcher m = Pattern.compile(
		// "GRAPH_(PIE|TIME)[\\s]*[\\[]([^\\]]+)[\\]]",
		// Pattern.CASE_INSENSITIVE).matcher(str);
		// System.out.println(m.find());
		//
		// System.out.println(parse("-- graph_time[ Biorhythm:1:2,3,4 ]"));

		String str2 = "LAUNCH IDX=1 onClick ";
		Matcher m3 = PROGRAM_LAUNCH.matcher(str2);
		while (m3.find()) {
			if (m3.groupCount() >= 3) {
				System.out.println("m3 found m.group1=" + m3.group(1)
						+ "// m.group3=" + LaunchTimingType.parse(m3.group(3)));
			} else {
				System.out.println("m3 found m.group1=" + m3.group(1));
			}

		}

	}
}
