package eu.dnetlib.actionmanager.actions;

import java.io.StringReader;
import java.util.List;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.util.Bytes;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
import org.dom4j.io.SAXReader;

import com.google.common.collect.Lists;

import eu.dnetlib.actionmanager.ActionManagerConstants.ACTION_TYPE;
import eu.dnetlib.actionmanager.common.Agent;
import eu.dnetlib.actionmanager.common.Operation;
import eu.dnetlib.actionmanager.common.Provenance;

public class XsltInfoPackageAction extends AbstractMetaAction<String> {

	private final Transformer transformer;

	private static final Log log = LogFactory.getLog(XsltInfoPackageAction.class); // NOPMD by marko on 11/24/08 5:02 PM

	protected XsltInfoPackageAction(String set, Agent agent, Operation operation, String infoPackage, Transformer transformer, ActionFactory actionFactory) {
		super(set, agent, operation, infoPackage, actionFactory);
		this.transformer = transformer;
	}

	private Document applyXslt(String xml, Provenance provenance, String trust, String nsprefix) throws DocumentException, TransformerException {
		Document doc = (new SAXReader()).read(new StringReader(xml));

		final DocumentResult result = new DocumentResult();

		transformer.setParameter("trust", trust);
		transformer.setParameter("provenance", provenance.toString());
		transformer.setParameter("namespaceprefix", nsprefix);

		transformer.transform(new DocumentSource(doc), result);

		//System.out.println(result.getDocument().asXML());

		return result.getDocument();
	}

	@Override
	protected List<AtomicAction> calculateAtomicActions(Provenance provenance, String trust, String nsprefix) {
		List<AtomicAction> list = Lists.newArrayList();

		try {
			Document doc = applyXslt(getMetaContent(), provenance, trust, nsprefix);
			for (Object o : doc.selectNodes("//ACTION")) {
				list.add(createAtomicAction((Element) o));
			}
		} catch (Exception e) {
			log.error("Error generating actions", e);
		}

		return list;
	}

	private AtomicAction createAtomicAction(Element elem) {
		String key = elem.valueOf("./@targetKey");
		String colFamily = elem.valueOf("./@targetColumnFamily");
		String col = elem.valueOf("./@targetColumn");
		String value64 = elem.getTextTrim();
		byte[] value = value64.isEmpty() ? null : Base64.decodeBase64(value64);

		return getActionFactory().createAtomicAction(getSet(), getAgent(), key, colFamily, col, value);
	}

	@Override
	public boolean isValid() {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public ACTION_TYPE getTypology() {
		return ACTION_TYPE.pkg;
	}

	@Override
	protected byte[] getBytesContent(String content) {
		return Bytes.toBytes(content);
	}

}
