/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */

package org.apache.vysper.xmpp.modules.core.base.handler;

import org.apache.vysper.mina.MinaBackedSessionContext;
import org.apache.vysper.xml.fragment.XMLElementVerifier;
import org.apache.vysper.xmpp.addressing.EntityFormatException;
import org.apache.vysper.xmpp.addressing.EntityImpl;
import org.apache.vysper.xmpp.protocol.NamespaceURIs;
import org.apache.vysper.xmpp.protocol.ResponseStanzaContainer;
import org.apache.vysper.xmpp.protocol.ResponseStanzaContainerImpl;
import org.apache.vysper.xmpp.protocol.SessionStateHolder;
import org.apache.vysper.xmpp.protocol.StanzaHandler;
import org.apache.vysper.xmpp.protocol.StreamErrorCondition;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionContext;
import org.apache.vysper.xmpp.server.SessionState;
import org.apache.vysper.xmpp.server.XMPPVersion;
import org.apache.vysper.xmpp.server.response.ServerErrorResponses;
import org.apache.vysper.xmpp.server.response.ServerResponses;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.stanza.StanzaBuilder;

/**
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 */
public class StreamStartHandler implements StanzaHandler {
    public String getName() {
        return "stream";
    }

    public boolean verify(Stanza stanza) {
        if (stanza == null)
            return false;
        if (!getName().equals(stanza.getName()))
            return false;
        String namespaceURI = stanza.getNamespaceURI();
        if (namespaceURI == null)
            return false;
        return namespaceURI.equals(NamespaceURIs.JABBER_CLIENT) || namespaceURI.equals(NamespaceURIs.JABBER_SERVER);
    }

    public boolean isSessionRequired() {
        return true;
    }

    public ResponseStanzaContainer execute(Stanza stanza, ServerRuntimeContext serverRuntimeContext,
            boolean isOutboundStanza, SessionContext sessionContext, SessionStateHolder sessionStateHolder) {
        XMLElementVerifier xmlElementVerifier = stanza.getVerifier();
        boolean jabberNamespace = NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS.equals(stanza.getNamespaceURI());

        boolean clientCall = xmlElementVerifier.namespacePresent(NamespaceURIs.JABBER_CLIENT);
        boolean serverCall = xmlElementVerifier.namespacePresent(NamespaceURIs.JABBER_SERVER);

        // TODO is it better to derive c2s or s2s from the type of endpoint and verify the namespace here?
        if (clientCall && serverCall)
            serverCall = false; // silently ignore ambiguous attributes
        if (serverCall)
            sessionContext.setServerToServer();
        else
            sessionContext.setClientToServer();

        if (sessionStateHolder.getState() != SessionState.INITIATED
                && sessionStateHolder.getState() != SessionState.ENCRYPTED
                && sessionStateHolder.getState() != SessionState.AUTHENTICATED) {
            return respondUnsupportedStanzaType("unexpected stream start");
        }

        // http://etherx.jabber.org/streams cannot be omitted
        if (!jabberNamespace) {
            return respondIllegalNamespaceError("namespace is mandatory: "
                    + NamespaceURIs.HTTP_ETHERX_JABBER_ORG_STREAMS);
        }

        // processing xml:lang
        String xmlLang = stanza.getXMLLang();
        sessionContext.setXMLLang(xmlLang);

        // processing version
        XMPPVersion responseVersion = null;
        // if version is not present, version "0.0" is assumed, represented by NULL.
        String versionAttributeValue = stanza.getAttributeValue("version");
        if (versionAttributeValue != null) {
            XMPPVersion clientVersion;
            try {
                clientVersion = new XMPPVersion(versionAttributeValue);
            } catch (IllegalArgumentException e) {
                // version string does not conform to spec
                return respondUnsupportedVersionError(xmlLang, versionAttributeValue, "illegal version value: ");
            }
            // check if version is supported
            if (!clientVersion.equals(XMPPVersion.VERSION_1_0)) {
                if (clientVersion.getMajor() == XMPPVersion.VERSION_1_0.getMajor()) {
                    // we live with the higher minor version, but only support ours
                    responseVersion = XMPPVersion.VERSION_1_0;
                } else {
                    // we do not support major changes, as of RFC3920
                    return respondUnsupportedVersionError(xmlLang, versionAttributeValue,
                            "major version change not supported: ");
                }
            } else {
                responseVersion = clientVersion;
            }
        }

        if (xmlElementVerifier.attributePresent("id")) {
            // ignore silently (see RFC3920 4.4)
        }

        Stanza responseStanza = null;
        if (clientCall) {
            // RFC3920: 'to' attribute SHOULD be used by the initiating entity
            String toValue = stanza.getAttributeValue("to");
            if (toValue != null) {
                try {
                    EntityImpl.parse(toValue);
                } catch (EntityFormatException e) {
                    return new ResponseStanzaContainerImpl(ServerErrorResponses.getInstance().getStreamError(
                            StreamErrorCondition.IMPROPER_ADDRESSING, sessionContext.getXMLLang(),
                            "could not parse incoming stanza's TO attribute", null));

                }
                // TODO check if toEntity is served by this server
                // if (!server.doesServe(toEntity)) throw WhateverException();

                // TODO RFC3920: 'from' attribute SHOULD be silently ignored by the receiving entity
                // TODO RFC3920bis: 'from' attribute SHOULD be not ignored by the receiving entity and used as 'to' in responses
            }
            responseStanza = new ServerResponses().getStreamOpenerForClient(sessionContext.getServerJID(),
                    responseVersion, sessionContext);
        } else if (serverCall) {
            // RFC3920: 'from' attribute SHOULD be used by the receiving entity
            String fromValue = stanza.getAttributeValue("from");
            if (fromValue != null) {
                try {
                    EntityImpl.parse(fromValue);
                } catch (EntityFormatException e) {
                    return new ResponseStanzaContainerImpl(ServerErrorResponses.getInstance().getStreamError(
                            StreamErrorCondition.INVALID_FROM, sessionContext.getXMLLang(),
                            "could not parse incoming stanza's FROM attribute", null));
                }
            }

            responseStanza = new ServerResponses().getStreamOpenerForServerAcceptor(sessionContext.getServerJID(),
                    responseVersion, sessionContext, serverRuntimeContext.getSslContext() != null);
        } else {
            String descriptiveText = "one of the two namespaces must be present: " + NamespaceURIs.JABBER_CLIENT
                    + " or " + NamespaceURIs.JABBER_SERVER;
            return respondIllegalNamespaceError(descriptiveText);
        }

        // if all is correct, go to next phase
        switch (sessionStateHolder.getState()) {

        case AUTHENTICATED:
        case ENCRYPTED:
            // do not change state!
            break;
        default:
            sessionStateHolder.setState(SessionState.STARTED);
        }

        if (responseStanza != null)
            return new ResponseStanzaContainerImpl(responseStanza);

        return null;
    }

    private ResponseStanzaContainer respondIllegalNamespaceError(String descriptiveText) {
        return new ResponseStanzaContainerImpl(ServerErrorResponses.getInstance().getStreamError(
                StreamErrorCondition.INVALID_NAMESPACE, null, descriptiveText, null));
    }

    private ResponseStanzaContainer respondUnsupportedStanzaType(String descriptiveText) {
        return new ResponseStanzaContainerImpl(ServerErrorResponses.getInstance().getStreamError(
                StreamErrorCondition.UNSUPPORTED_STANZA_TYPE, null, descriptiveText, null));
    }

    private ResponseStanzaContainer respondUnsupportedVersionError(String xmlLang, String versionAttributeValue,
            String errorMessage) {
        if (xmlLang == null)
            xmlLang = "en_US";
        Stanza error = ServerErrorResponses.getInstance().getStreamError(StreamErrorCondition.UNSUPPORTED_VERSION,
                xmlLang, errorMessage + versionAttributeValue, null);
        return new ResponseStanzaContainerImpl(error);
    }

}
