package jp.ac.naka.ec.sensor;

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.DataType;

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 SensorDataParserImpl implements SensorDataParser, ErrorHandler {
	private static DocumentBuilder db;
	private static SensorDataParserImpl instance = new SensorDataParserImpl();
	
	private SensorDataParserImpl() {}
	
	public static SensorDataParser getInstance() throws ParserConfigurationException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 検証を行う
		// dbf.setValidating(true);
		// ドキュメントビルダーを生成
		db = dbf.newDocumentBuilder();
		db.setErrorHandler(instance);
		return instance;
	}
	
	public SensorData parse(String eiml) throws SAXException, IOException {
		return parse(eiml.getBytes());
	}
	
	public SensorData parse (byte[] content) throws SAXException, IOException {
		Document doc = db.parse(new ByteArrayInputStream(content), "UTF-8");
		Element root = doc.getDocumentElement();
		
		return parse(root);
	}

	public SensorData parse(Element root) {
		SensorData data = new SensorDataImpl();
		String name = root.getAttribute("name");
		String temp =  root.getAttribute("ttl");
		long ttl = 60;
		if (temp != null && !temp.equals(""))
			ttl = Long.valueOf(temp);
		NodeList list = root.getElementsByTagName("device");
		// TODO
		Device device = getDevice(list);
		
		list = root.getElementsByTagName("location");
		Location location = getLocation (list.item(0));
		
		list = root.getElementsByTagName("data");
		Node node = list.item(0);
		String data_name = null, type = null, measure = null, value = null;
		if (node != null) {
			NamedNodeMap oAttrs = node.getAttributes();
			data_name = oAttrs.getNamedItem("name").getNodeValue();
			type = oAttrs.getNamedItem("type").getNodeValue();
			measure = oAttrs.getNamedItem("measure").getNodeValue();
			value = node.getFirstChild().getNodeValue();
		}
		
		data.setName(name);
		data.setTTL(ttl);
		data.setDevice(device);
		data.setLocation(location);
		data.setDataName(data_name);
		if (type != null)
			data.setDataType(DataType.valueOf(type));
		data.setMeasure(measure);
		data.setData(value);
		return data;
	}
	
	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;
	}

	private Device getDevice(NodeList list) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	/*
	 * (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();
	}
	
	public static void main(String[] arg) {
		
	}

	
}
