package edutainmentclient;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.jivesoftware.smack.packet.Message;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author Gonzalo
 */
public class LocationMessage {

    //Message type codes
    public static final int ANSWER_MESSAGE = 1;
    public static final int EVENT_MESSAGE = 2;

    //Parsing error codes
    public static final int NOT_XML_FORMAT = 1;
    public static final int NOT_LOCATION_MESSAGE = 2;
    public static final int NO_SUCH_MESSAGE_TYPE = 3;
    public static final int MISSING_USER_ID = 4;

    private int messageTypeCode;
    private int errorCode = 0;
    //Valores extraidos de un mensaje tipo 'ans'
    private String result;
    private String code;
    private String text;
    
    //Valores extraidos de un mensaje tipo 'eve'
    private String ruleId;
    private Vector<Pair> vPairs = null;
    private String locName;
    private String locCoor;
    private String locDate;


    public boolean parseMessage(Message message) {
        try {
            String messageBody = message.getBody();
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new ByteArrayInputStream(messageBody.getBytes()));

            XPathFactory xpf = XPathFactory.newInstance();
            XPath xpath = xpf.newXPath();

            String mainElement = ((Node) xpath.evaluate("/*", doc, XPathConstants.NODE)).getNodeName();
          //  System.out.println("mainElement "+mainElement);

            //Si el mensaje tiene como tag principal osami es correcto y lo processamos
            if (mainElement.equals("osami")) {
                String messageType = (String) xpath.evaluate("/osami/@type", doc, XPathConstants.STRING);
                //System.out.println("messageType "+messageType);

                if (messageType.equals("ans")) {
                    messageTypeCode = ANSWER_MESSAGE;
                    result = (String) xpath.evaluate("/osami/message/result/text()",doc,XPathConstants.STRING);
                    code = (String) xpath.evaluate("/osami/message/code/text()",doc,XPathConstants.STRING);
                    text = (String) xpath.evaluate("/osami/message/text/text()",doc,XPathConstants.STRING);
                    return true;
                } else if (messageType.equals("eve")) {
                    messageTypeCode = EVENT_MESSAGE;
                    ruleId = (String) xpath.evaluate("/osami/rule/id/text()", doc, XPathConstants.STRING);
                    NodeList pairs = (NodeList) xpath.evaluate("/osami/pairs/pair", doc, XPathConstants.NODESET);
                    if (pairs.getLength() > 0) {
                       // System.out.println("hay parejas");
                        vPairs = new Vector<Pair>();
                        for (int i=0;i<pairs.getLength();i++) {
                            Node pair = pairs.item(i);
                            String deviceId = (String) xpath.evaluate("./device/id/text()", pair, XPathConstants.STRING);
                            String deviceInRange = (String) xpath.evaluate("./device/@range", pair, XPathConstants.STRING);
                            String userId = (String) xpath.evaluate("./user/name/text()", pair, XPathConstants.STRING);
                            getvPairs().add(new Pair(deviceId, deviceInRange, userId));
                        }
                    } else {
                       // System.out.println("no hay parejas");
                    }
                    locName = (String) xpath.evaluate("/osami/localization/name/text()", doc, XPathConstants.STRING);
                    locCoor = (String) xpath.evaluate("/osami/localization/coor/text()", doc, XPathConstants.STRING);
                    locDate = (String) xpath.evaluate("/osami/localization/date/text()", doc, XPathConstants.STRING);
                    return true;
                } else {
                    errorCode = NO_SUCH_MESSAGE_TYPE;
                    return false;
                }


            } else {
                errorCode = NOT_LOCATION_MESSAGE;
                return false;
            }

        } catch (XPathExpressionException ex) {
            ex.printStackTrace();
        } catch (SAXException ex) {
            errorCode = NOT_XML_FORMAT;
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ParserConfigurationException ex) {
            ex.printStackTrace();

        }
        return false;
    }

    /**
     * @return the messageTypeCode
     */
    public int getMessageTypeCode() {
        return messageTypeCode;
    }

    /**
     * @return the errorCode
     */
    public int getErrorCode() {
        return errorCode;
    }

    /**
     * @return the result
     */
    public String getResult() {
        return result;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @return the text
     */
    public String getText() {
        return text;
    }

    /**
     * @return the ruleId
     */
    public String getRuleId() {
        return ruleId;
    }

    /**
     * @return the vPairs
     */
    public Vector<Pair> getvPairs() {
        return vPairs;
    }

    /**
     * @return the locName
     */
    public String getLocName() {
        return locName;
    }

    /**
     * @return the locCoor
     */
    public String getLocCoor() {
        return locCoor;
    }

    /**
     * @return the locDate
     */
    public String getLocDate() {
        return locDate;
    }
}
