package org.deft.extension.trim;

import java.io.File;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.deft.extension.tokenlayouter.TokenLayouter;

import org.deft.repository.ast.TreeNode;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


//REFAC
public class AutoTrimmer {

	private enum TrimDirection {
		NONE, LEFT, RIGHT, BOTH
	};

	private static final Logger LOGGER = Logger.getLogger(AutoTrimmer.class);

	private TokenLayouter tl;
	private HashMap<String, TrimDirection> trimMap = new HashMap<String, TrimDirection>();
	private String trimerDescriptionFile;

	static {
		// OPT LOGGER
		LOGGER.addAppender(new ConsoleAppender(new SimpleLayout()));
	}

	public AutoTrimmer(TreeNode root, String trimerDescriptionFile) {

		this.trimerDescriptionFile = trimerDescriptionFile;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		Document document;
		try {
			builder = factory.newDocumentBuilder();
			document = builder.parse(new File(trimerDescriptionFile));
		} catch (Exception e) {
			throw new TrimmerException(e.toString());
		}

		load(document, "trimLeft", TrimDirection.LEFT);
		load(document, "trimRight", TrimDirection.RIGHT);
		load(document, "trimBoth", TrimDirection.BOTH);
		load(document, "trimNone", TrimDirection.NONE);

		tl = new TokenLayouter(root.serialize());

	}

	private void load(Document document, String tag, TrimDirection td) {
		NodeList nl = document.getElementsByTagName(tag);
		if (nl.getLength() != 1)
			throw new TrimmerException("Invalid number of '" + tag + "' tags");
		Node n = nl.item(0);
		String content = n.getTextContent();
		String[] tokens = content.split(",");
		for (int c = 0, s = tokens.length; c < s; c++) {
			trimMap.put(tokens[c].trim(), td);
		}
	}

	public void trim(TreeNode tn) {
		TrimDirection td = trimMap.get(tn.getName());
		if (td == null) {
			// TODO Logger
			LOGGER.warn("Unhandled trim: " + tn.getName() + "["
					+ tn.getFirstTokenNode().getName() + ","
					+ tn.getLastTokenNode().getName() + "] in "
					+ trimerDescriptionFile);
			return;
		}
		switch (td) {
		case LEFT:
			tl.trimLeft(tn.getFirstToken());
			break;
		case RIGHT:
			tl.trimRight(tn.getLastToken());
			break;
		case BOTH:
			tl.trimLeft(tn.getFirstToken());
			tl.trimRight(tn.getLastToken());
			break;
		case NONE:
			break;
		}
	}
}
