package org.etsi.mts.ttcn.part9.xmldiff;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.custommonkey.xmlunit.Difference;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class DiffErrorHandler implements ErrorHandler {
	private List<SAXParseException> errors = new ArrayList<SAXParseException>();
	private List<SAXParseException> warnings = new ArrayList<SAXParseException>();
	private static final String NEWLINE = System.getProperty("line.separator");
	private boolean hasErrors = false;
	
	private StringBuilder description = new StringBuilder();
	private String source;
	private String kind;
	
	public String getErrorsText() {
		return description.toString();
	}
	
	public boolean hasErrors() {
		return hasErrors;
	}
	
	public synchronized void reset(boolean clearLog) {
		hasErrors = false;
		if (clearLog) {
			description = new StringBuilder();
		}
	}
	/*************************************************************
	 * 
	 * Parser error handler
	 * 
	 *************************************************************/
	//@Override
	public void error(SAXParseException err) throws SAXException {
		errors.add(err);
		appendDescripion(err);
		hasErrors = true;
		XmlDiff.logger.severe("Error while parsing ", kind, ": ", err.getMessage(), "\nDocument: \n", source);
	}

	//@Override
	public void fatalError(SAXParseException err) throws SAXException {
		errors.add(err);
		appendDescripion(err);
		hasErrors = true;
		XmlDiff.logger.severe("Fatal error while parsing ", kind, ": ", err.getMessage(), "\nDocument: \n", source);
	}

	private synchronized void appendDescripion(Throwable err) {
		StringWriter sw = new StringWriter();
		err.printStackTrace(new PrintWriter(sw));
		description.append(sw).append(NEWLINE);
	}
	//@Override
	public void warning(SAXParseException warn) throws SAXException {
		warnings.add(warn);
		XmlDiff.logger.warning("Warning while parsing ", kind, ": ", warn.getMessage(), "\nDocument: \n", source);
	}

	/************************************************************
	 * 
	 * Differences
	 * 
	 ************************************************************/
	public void difference(Difference diff) {
		hasErrors = true;
		appendDescripion(diff);
	}
	
	private synchronized void appendDescripion(Difference diff) {
		description.append(diff.getDescription()).append(NEWLINE);
	}

	public void setSource(String string) {
		this.source = string;
	}

	public void setKind(String kind) {
		this.kind = kind;
	}
}