package edutainmentclient;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
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.xml.sax.SAXException;

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

    //Message type codes
    public static final int START_REQUEST = 1;
    public static final int STOP_REQUEST = 2;
    public static final int PING_REQUEST = 3;
    public static final int CONTENT_REQUEST = 4;
    //Parsing error codes
    public static final int NOT_XML_FORMAT = 1;
    public static final int NOT_EDUTAINMENT_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;
    private String userId = "";
    private String courseId = "";
    private String courseURL="";
    private String scoId = "";
    private String scoPath="";
    private float scoTimestamp = 0;

    public boolean parseMessage(Message message) {

        try {
            String messageBody = message.getBody();

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = null;

            doc = db.parse(new ByteArrayInputStream(messageBody.getBytes()));

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

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



            //Si el mensaje tiene como tag principal edutaiment es correcto y lo processamos
            if (mainElement.equals("edutainment")) {
                String messageType = (String) xpath.evaluate("/edutainment/@type", doc, XPathConstants.STRING);
                System.out.println(messageType);
                if (messageType.equals("clientStartReq")) {
                    messageTypeCode = START_REQUEST;
                    userId = (String) xpath.evaluate("/edutainment/user/@id", doc, XPathConstants.STRING);
                    //dejamos el userId como opcional
                    // if (!userId.equals("")) {
                    Node course = (Node) xpath.evaluate("/edutainment/course", doc, XPathConstants.NODE);
                    if (course != null) {
                        courseId = (String) xpath.evaluate("./id/text()", course, XPathConstants.STRING);
                        // System.out.println("courseId es " + courseId);
                        Node sco = (Node) xpath.evaluate("./sco", course, XPathConstants.NODE);
                        if (sco != null) {
                            scoId = (String) xpath.evaluate("./@id", sco, XPathConstants.STRING);
                            // System.out.println("scoId es " + scoId);
                            scoTimestamp = Float.parseFloat(((String) xpath.evaluate("./@timestamp", sco, XPathConstants.STRING)));
                            //System.out.println("scoTimestamp es " + scoTimestamp);
                            scoPath= (String) xpath.evaluate("./@scoPath", sco, XPathConstants.STRING);
                        } else {
                            scoId = "";
                            scoPath="";
                            scoTimestamp = 0;
                        }
                        courseURL=(String) xpath.evaluate("./url/text()", course, XPathConstants.STRING);
                    } else {
                        courseId = "";
                        scoId = "";
                        scoPath="";
                        scoTimestamp = 0;
                    }

                    //dejamos el userId como opcional
                    /*
                    } else {
                    errorCode = MISSING_USER_ID;
                    return false;
                    }
                     * */

                } else if (messageType.equals("clientStopReq")) {
                    messageTypeCode = STOP_REQUEST;
                } else if (messageType.equals("pingReq")) {
                    messageTypeCode = PING_REQUEST;
                } else if (messageType.equals("getContentReq")) {
                    messageTypeCode = CONTENT_REQUEST;
                    userId = (String) xpath.evaluate("/edutainment/user/@id", doc, XPathConstants.STRING);
                } else {
                    errorCode = NO_SUCH_MESSAGE_TYPE;
                    return false;
                }


                return true;
            } else {
                errorCode = NOT_EDUTAINMENT_MESSAGE;
                return false;
            }

        } catch (SAXException ex) {
            Logger.getLogger(EdutainmentMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(EdutainmentMessage.class.getName()).log(Level.SEVERE, null, ex);
        } catch (XPathExpressionException 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 userId
     */
    public String getUserId() {
        return userId;
    }

    /**
     * @return the courseId
     */
    public String getCourseId() {
        return courseId;
    }

    /**
     * @return the scoId
     */
    public String getScoId() {
        return scoId;
    }

    /**
     * @return the scoTimestamp
     */
    public float getScoTimestamp() {
        return scoTimestamp;
    }

    public String getScoPath(){
        return scoPath;
    }

    public String getcourseURL(){
        return courseURL;
    }
}
