package com.testingtech.tri.extfct;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.MessageFormat;

import org.etsi.mts.ttcn.part9.xmldiff.XmlDiff;
import org.etsi.ttcn.tci.BooleanValue;
import org.etsi.ttcn.tci.RecordOfValue;
import org.etsi.ttcn.tci.UniversalCharstringValue;

import com.testingtech.ttcn.annotation.ExternalFunction;
import com.testingtech.ttcn.tri.AnnotationsExternalFunctionPlugin;
import com.testingtech.util.FileUtil;

import de.tu_berlin.cs.uebb.muttcn.runtime.TestCaseError;

@ExternalFunction.Definitions(XmlDiffExtFctPlugin.class)
public class XmlDiffExtFctPlugin extends AnnotationsExternalFunctionPlugin {

	// external function matchFile(Raw p_textToMatch, universal charstring p_referenceXmlFile, XsdFileList p_xsdFileList, out universal charstring p_matchError) return boolean;
	@ExternalFunction(name = "matchFile")
	public BooleanValue matchFile_2(UniversalCharstringValue p_textToMatch,
			UniversalCharstringValue p_referenceXmlFile, RecordOfValue xsdFileList, UniversalCharstringValue p_matchError) {
        String stringToMatch = p_textToMatch.getString();
        String strReferenceXmlFile = p_referenceXmlFile.getString();
        String[] xsdFileArray = null;
        if (xsdFileList.getLength() > 0) {
            xsdFileArray = new String[xsdFileList.getLength()];
            for(int i = 0; i < xsdFileList.getLength(); i++) {
                ((UniversalCharstringValue)xsdFileList.getField(i)).getString();
            }
        }
        String description = "";
        boolean res = false;
        try {
            XmlDiff diff = new XmlDiff(strReferenceXmlFile, xsdFileArray, null);
            StringBuilder sb = new StringBuilder();
            res = diff.diff(stringToMatch, sb);
            if (sb.length() > 0)
                description = sb.toString();
        } catch (Exception e) {
            description = e.getMessage();
        }
        if (!res && description == null)
            description = "Unspecified error";
        
        p_matchError.setString(description);
        
        return newBooleanValue(res);
    }
	
	//external function readFile(universal charstring p_referenceXmlFile) return universal charstring;
	@ExternalFunction(name = "readFile")
	public UniversalCharstringValue readFile(UniversalCharstringValue p_referenceXmlFile) {
	    FileInputStream in = null;
	    try {
	      File file = new File(p_referenceXmlFile.getString());
	      in = new FileInputStream(file);
	      ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
	      FileUtil.copy(in, out);
	      return newUniversalCharstringValue(out.toString("UTF-8"));
	    } catch (Throwable e) {
	      throw new TestCaseError(new RuntimeException(MessageFormat.format("error while reading UTF-8 encoded file: {0} {1}", p_referenceXmlFile.getString(), e.toString()), e));
	    } finally {
	      try {
	        in.close();
	      } catch (Throwable e) {
	        // ignore exception
	      }
	    }
	}

}
