/*
 *  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.mina;

import java.util.concurrent.TimeUnit;

import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.vysper.mina.codec.StanzaWriteInfo;
import org.apache.vysper.xmpp.protocol.SessionStateHolder;
import org.apache.vysper.xmpp.server.AbstractSessionContext;
import org.apache.vysper.xmpp.server.ServerRuntimeContext;
import org.apache.vysper.xmpp.server.SessionState;
import org.apache.vysper.xmpp.stanza.Stanza;
import org.apache.vysper.xmpp.writer.StanzaWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * connects MINA 2 frontend to the vysper backend
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 */
public class MinaBackedSessionContext extends AbstractSessionContext implements StanzaWriter, IoFutureListener {

    final Logger logger = LoggerFactory.getLogger(MinaBackedSessionContext.class);

    private IoSession minaSession;

    private boolean openingStanzaWritten = false;

    private boolean switchToTLS = false;
    private boolean clientTLS = false;

    protected CloseFuture closeFuture;

    public MinaBackedSessionContext(ServerRuntimeContext serverRuntimeContext, SessionStateHolder sessionStateHolder,
            IoSession minaSession) {
        super(serverRuntimeContext, sessionStateHolder);
        this.minaSession = minaSession;
        closeFuture = minaSession.getCloseFuture();
        closeFuture.addListener(this);
        sessionStateHolder.setState(SessionState.INITIATED); // connection established
    }

    public StanzaWriter getResponseWriter() {
        return this;
    }

    public void switchToTLS(boolean delayed, boolean clientTls) {
        this.clientTLS = clientTls;

        if(delayed) {
            switchToTLS = true;
        } else {
            addSslFilter();
        }
    }

    public void setIsReopeningXMLStream() {
        openingStanzaWritten = false;
    }
    
    private void addSslFilter() {
        
        minaSession.suspendRead();
        minaSession.suspendWrite();
        SslFilter filter = new SslFilter(getServerRuntimeContext().getSslContext());
        filter.setUseClientMode(clientTLS);
        minaSession.getFilterChain().addFirst("sslFilter", filter);
        if(!clientTLS) {
            minaSession.setAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE);
        }
        minaSession.setAttribute(SslFilter.USE_NOTIFICATION, Boolean.TRUE);
        minaSession.resumeWrite();
        minaSession.resumeRead();
        
    }

    public void write(Stanza stanza) {
        if (switchToTLS) {
            addSslFilter();
            switchToTLS = false;
        }

        minaSession.write(new StanzaWriteInfo(stanza, !openingStanzaWritten));
        openingStanzaWritten = true;
    }

    public void close() {
        logger.info("session will be closed now");
        closeFuture.setClosed();
        try {
            // allow some time to flush before closibng
            if(!minaSession.close(false).await(5000, TimeUnit.MILLISECONDS)) {
                // no really close if necessary
                minaSession.close(true);
            }
        } catch (InterruptedException e) {
            // ignore
        }
        logger.info("session closed");
    }

    public void operationComplete(IoFuture ioFuture) {
        // close future notification
        logger.info("close future called");
    }
}
