//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server;

import java.io.IOException;
import java.util.List;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;

import org.eclipse.jetty.io.AbstractConnection;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

public abstract class NegotiatingServerConnection extends AbstractConnection
{
    private static final Logger LOG = Log.getLogger(NegotiatingServerConnection.class);

    public interface CipherDiscriminator
    {
        boolean isAcceptable(String protocol, String tlsProtocol, String tlsCipher);
    }
    
    private final Connector connector;
    private final SSLEngine engine;
    private final List<String> protocols;
    private final String defaultProtocol;
    private String protocol; // No need to be volatile: it is modified and read by the same thread

    protected NegotiatingServerConnection(Connector connector, EndPoint endPoint, SSLEngine engine, List<String> protocols, String defaultProtocol)
    {
        super(endPoint, connector.getExecutor());
        this.connector = connector;
        this.protocols = protocols;
        this.defaultProtocol = defaultProtocol;
        this.engine = engine;
    }

    protected List<String> getProtocols()
    {
        return protocols;
    }

    protected String getDefaultProtocol()
    {
        return defaultProtocol;
    }

    protected Connector getConnector()
    {
        return connector;
    }
    
    protected SSLEngine getSSLEngine()
    {
        return engine;
    }

    protected String getProtocol()
    {
        return protocol;
    }

    protected void setProtocol(String protocol)
    {
        this.protocol = protocol;
    }

    @Override
    public void onOpen()
    {
        super.onOpen();
        fillInterested();
    }

    @Override
    public void onFillable()
    {
        int filled = fill();

        if (filled == 0)
        {
            if (protocol == null)
            {
                if (engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
                {
                    // Here the SSL handshake is finished, but the protocol has not been negotiated.
                    if (LOG.isDebugEnabled())
                        LOG.debug("{} could not negotiate protocol, SSLEngine: {}", this, engine);
                    close();
                }
                else
                {
                    // Here the SSL handshake is not finished yet but we filled 0 bytes,
                    // so we need to read more.
                    fillInterested();
                }
            }
            else
            {
                ConnectionFactory connectionFactory = connector.getConnectionFactory(protocol);
                if (connectionFactory == null)
                {
                    LOG.info("{} application selected protocol '{}', but no correspondent {} has been configured",
                             this, protocol, ConnectionFactory.class.getName());
                    close();
                }
                else
                {
                    EndPoint endPoint = getEndPoint();
                    Connection newConnection = connectionFactory.newConnection(connector, endPoint);
                    endPoint.upgrade(newConnection);
                }
            }
        }
        else if (filled < 0)
        {
            // Something went bad, we need to close.
            if (LOG.isDebugEnabled())
                LOG.debug("{} detected close on client side", this);
            close();
        }
        else
        {
            // Must never happen, since we fill using an empty buffer
            throw new IllegalStateException();
        }
    }

    private int fill()
    {
        try
        {
            return getEndPoint().fill(BufferUtil.EMPTY_BUFFER);
        }
        catch (IOException x)
        {
            LOG.debug(x);
            close();
            return -1;
        }
    }

    @Override
    public void close()
    {
        // Gentler close for SSL.
        getEndPoint().shutdownOutput();
        super.close();
    }
}
