package com.tandbergtv.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import junit.framework.TestCase;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import com.tandbergtv.metadatamanager.model.CustomField;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.metadatamanager.util.FieldBinder;

/**
 * FieldBinderTest - tests the field binder's ability to convert a document
 * containing a tns:Field root into a List<Field> and then back again.
 * 
 * @author nicholas
 * 
 */
public class FieldBinderTest extends TestCase {

	private static final String TEST_OUTPUT_FILE = "tests/com/tandbergtv/util/output.xml";
	private static final String TEST_INPUT_FILE = "tests/com/tandbergtv/spec/sampleInput/my-translationOutput.xml";
	private Document outPutDoc = null;

	/**
	 * Tests field binder creating a list of fields from a document and back
	 * again.
	 */
	public void testFieldBinder() {
		// buildXml(extractXPaths());
		List<Field> fields = extractXPaths();
		for (Field field : fields) {
			System.out.println(field);
		}
	}

	public void _testGetCustFields() {
		Collection<CustomField> customFields = new FieldBinder().getCustomFields(createFieldsXPath());
		assertEquals(2, customFields.size());
		CustomField customField = new CustomField(
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields{1}/tns:CustomField{1}", "CUST_NAME",
				"CUST_VALUE");
		assertTrue(customFields.contains(customField));
		CustomField customField2 = new CustomField(
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields-CL1_1{1}/tns:CustomField{1}",
				"CL11_Trial2", "Trial_value2");
		assertTrue(customFields.contains(customField2));
	}

	/**
	 * Tests field binder creating a list of fields from a document.
	 * 
	 * @return List<Field>
	 */
	private List<Field> extractXPaths() {
		try {
			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
			Document doc = builder.parse(new File(TEST_INPUT_FILE));
			return new FieldBinder().extractXPaths(doc);
		} catch (ParserConfigurationException e) {
		} catch (SAXException e) {
		} catch (IOException e) {
		}
		return null;
	}

	/**
	 * Tests field binder creating a document form a list of fields.
	 * 
	 * @param fieldList
	 */
	@SuppressWarnings("unused")
	private void buildXml(List<Field> fieldList) {

		outPutDoc = new FieldBinder().buildXml(fieldList);
		File output = new File(TEST_OUTPUT_FILE);
		print(outPutDoc, output);
		System.out.println("Done building.");
	}

	private void print(Document doc, File outFile) {

		if (doc == null) {
			return;
		}

		try {
			OutputFormat format = new OutputFormat(doc);
			format.setIndenting(true);
			XMLSerializer serializer = new XMLSerializer(new FileOutputStream(outFile, false), format);
			serializer.serialize(doc);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private List<String> createFieldsXPath() {
		String[] testStrs = new String[] {
				"/tns:TTVSpec{1}/tns:Group{1}/tns:Fields{1}/tns:CustomFields{1}==",
				"/tns:TTVSpec{1}/tns:Group{1}/tns:Fields{1}/tns:CustomFields-CL1_1{1}==",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields{1}/tns:CustomField{1}/@Name==CUST_NAME",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields{1}/tns:CustomField{1}/@Value==CUST_VALUE",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields{1}/tns:CustomField{1}==",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields-CL1_1{1}/tns:CustomField{1}/@Name==CL11_Trial2",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields-CL1_1{1}/tns:CustomField{1}/@Value==Trial_value2",
				"/tns:TTVSpec{1}/tns:Item{1}/tns:Fields{1}/tns:CustomFields-CL1_1{1}/tns:CustomField{1}==",

		};

		return Arrays.asList(testStrs);

	}
}
