/*
 * ====================================================================
 * 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

package org.apache.hc.core5.http2.impl.nio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.hc.core5.annotation.Internal;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.impl.nio.BufferedData;
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
import org.apache.hc.core5.reactor.IOSession;
import org.apache.hc.core5.reactor.ProtocolIOSession;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
import org.apache.hc.core5.util.Args;
import org.apache.hc.core5.util.TextUtils;

/**
 * I/O event handler for events fired by {@link ProtocolIOSession} that implements
 * client side of the HTTP/2 protocol negotiation handshake always forcing the choice
 * of HTTP/2.
 *
 * @since 5.2
 */
@Internal
public class ClientH2PrefaceHandler extends PrefaceHandlerBase {

    // PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
    final static byte[] PREFACE = new byte[] {
            0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, 0x54, 0x50,
            0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, 0x53, 0x4d,
            0x0d, 0x0a, 0x0d, 0x0a};

    private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
    private final boolean strictALPNHandshake;
    private final AtomicBoolean initialized;

    private volatile ByteBuffer preface;
    private volatile BufferedData inBuf;

    public ClientH2PrefaceHandler(
            final ProtocolIOSession ioSession,
            final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
            final boolean strictALPNHandshake) {
        this(ioSession, http2StreamHandlerFactory, strictALPNHandshake, null);
    }

    /**
     * @since 5.1
     */
    public ClientH2PrefaceHandler(
            final ProtocolIOSession ioSession,
            final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
            final boolean strictALPNHandshake,
            final FutureCallback<ProtocolIOSession> resultCallback) {
        super(ioSession, resultCallback);
        this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
        this.strictALPNHandshake = strictALPNHandshake;
        this.initialized = new AtomicBoolean();
    }

    private void initialize() throws IOException {
        final TlsDetails tlsDetails = ioSession.getTlsDetails();
        if (tlsDetails != null) {
            final String applicationProtocol = tlsDetails.getApplicationProtocol();
            if (TextUtils.isEmpty(applicationProtocol)) {
                if (strictALPNHandshake) {
                    throw new ProtocolNegotiationException("ALPN: missing application protocol");
                }
            } else {
                if (!ApplicationProtocol.HTTP_2.id.equals(applicationProtocol)) {
                    throw new ProtocolNegotiationException("ALPN: unexpected application protocol '" + applicationProtocol + "'");
                }
            }
        }
        this.preface = ByteBuffer.wrap(PREFACE);
        ioSession.setEvent(SelectionKey.OP_WRITE);
    }

    /**
     * @return true if the entire preface has been written out
     */
    private boolean writeOutPreface(final IOSession session, final ByteBuffer preface) throws IOException  {
        if (preface.hasRemaining()) {
            session.write(preface);
        }
        if (!preface.hasRemaining()) {
            session.clearEvent(SelectionKey.OP_WRITE);
            final ByteBuffer data = inBuf != null ? inBuf.data() : null;
            startProtocol(new ClientH2IOEventHandler(http2StreamHandlerFactory.create(ioSession)), data);
            if (inBuf != null) {
                inBuf.clear();
            }
            return true;
        }
        return false;
    }

    @Override
    public void connected(final IOSession session) throws IOException {
        if (initialized.compareAndSet(false, true)) {
            initialize();
        }
    }

    @Override
    public void outputReady(final IOSession session) throws IOException {
        if (initialized.compareAndSet(false, true)) {
            initialize();
        }
        final ByteBuffer preface = this.preface;
        if (preface != null) {
            if (writeOutPreface(session, preface)) {
                this.preface = null;
            }
        } else {
            throw new ProtocolNegotiationException("Unexpected output");
        }
    }

    @Override
    public void inputReady(final IOSession session, final ByteBuffer src) throws IOException {
        if (src != null) {
            if (inBuf == null) {
                inBuf = BufferedData.allocate(src.remaining());
            }
            inBuf.put(src);
        }
        final ByteBuffer preface = this.preface;
        if (preface != null) {
            if (writeOutPreface(session, preface)) {
                this.preface = null;
            }
        } else {
            throw new ProtocolNegotiationException("Unexpected input");
        }
    }

    @Override
    public String toString() {
        return getClass().getName();
    }

}
