package jp.ac.naka.ec.entity;

import java.io.ByteArrayInputStream;
import java.io.IOException;

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

import jp.ac.naka.ec.Location;
import jp.ac.naka.ec.sensor.SensorData;
import jp.ac.naka.ec.sensor.SensorDataParser;
import jp.ac.naka.ec.sensor.SensorDataParserImpl;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class EntityInformationParser implements ErrorHandler {
	private static DocumentBuilder db;
	private static EntityInformationParser instance = new EntityInformationParser();
	private static SensorDataParser parser;
	
	static {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 検証を行う
		// dbf.setValidating(true);
		// ドキュメントビルダーを生成
		try {
			db = dbf.newDocumentBuilder();
			db.setErrorHandler(instance);
			parser = SensorDataParserImpl.getInstance();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
	}
	
	public static EntityInformationParser getInstance ()  {
		return instance;
	}
	
	
	public EntityInformation parse(String content) throws SAXException, IOException  {
		return parse(content.getBytes());
	}
	
	public EntityInformation parse(byte[] content) throws SAXException, IOException  {
		Document doc = db.parse(new ByteArrayInputStream(content), "UTF-8");
		Element eiml = doc.getDocumentElement();
		String name = null, uri = null, type = null, description = "";
		Location location = null;
		SensorData[] sensors = null;
		
		Element root = (Element)eiml.getElementsByTagName("service").item(0);
		EntityInformation info = new EntityInformation();
		name = root.getAttribute("name");
		uri = root.getAttribute("uri");
		type = root.getAttribute("type");
		
		
		NodeList list = root.getElementsByTagName("location");
		location = getLocation (list.item(0));
		
		list = root.getElementsByTagName("sensor");
		
		sensors = new SensorData[list.getLength()];
		for (int i = 0 ; i <list.getLength(); i++) {
			Element element = (Element)list.item(i);
			sensors[i] = parser.parse(element);
		}
		
		list = root.getElementsByTagName("description");
		Node node = list.item(0);
		if (node != null) {
			Node temp = node.getFirstChild();
			if (temp != null)
				description = temp.getNodeValue();
		} 
		
		info.setServiceName(name);
		info.setServiceType(type);
		info.setDescription(description);
		info.setSensors(sensors);
		info.setUri(uri);
		info.setLocation(location);
		return info;
	}
	
	private Location getLocation(Node node) {
		if(node == null)
			return null;
		String name, lat, lon;
		Location location;
		NamedNodeMap oAttrs = node.getAttributes();
		name = oAttrs.getNamedItem("name").getNodeValue();
		lat = oAttrs.getNamedItem("latitude").getNodeValue();
		lon = oAttrs.getNamedItem("longitude").getNodeValue();
		
		if (name != null)
			location = new Location(name, lat, lon);
		else
			location = new Location(lat, lon);
		
		return location;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
	 */
	public void error(SAXParseException e) throws SAXException {
		e.printStackTrace();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
	 */
	public void fatalError(SAXParseException e) throws SAXException {
		e.printStackTrace();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
	 */
	public void warning(SAXParseException e) throws SAXException {
		e.printStackTrace();
	}
	
	
}
