/*
 *  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.coyote.http11.upgrade;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;

import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
import org.apache.tomcat.util.net.NioSelectorPool;
import org.apache.tomcat.util.net.SocketWrapper;

public class NioServletOutputStream extends AbstractServletOutputStream<NioChannel> {

    private final NioChannel channel;
    private final NioSelectorPool pool;
    private final int maxWrite;


    public NioServletOutputStream(SocketWrapper<NioChannel> socketWrapper,
            int asyncWriteBufferSize, NioSelectorPool pool) {
        super(socketWrapper, asyncWriteBufferSize);
        channel = socketWrapper.getSocket();
        this.pool = pool;
        maxWrite = channel.getBufHandler().getWriteBuffer().capacity();
    }


    @Override
    protected int doWrite(boolean block, byte[] b, int off, int len)
            throws IOException {
        int leftToWrite = len;
        int count = 0;
        int offset = off;

        while (leftToWrite > 0) {
            int writeThisLoop;
            int writtenThisLoop;

            if (leftToWrite > maxWrite) {
                writeThisLoop = maxWrite;
            } else {
                writeThisLoop = leftToWrite;
            }

            writtenThisLoop = doWriteInternal(block, b, offset, writeThisLoop);
            count += writtenThisLoop;
            offset += writtenThisLoop;
            leftToWrite -= writtenThisLoop;

            if (writtenThisLoop < writeThisLoop) {
                break;
            }
        }

        return count;
    }

    private int doWriteInternal (boolean block, byte[] b, int off, int len)
            throws IOException {
        channel.getBufHandler().getWriteBuffer().clear();
        channel.getBufHandler().getWriteBuffer().put(b, off, len);
        channel.getBufHandler().getWriteBuffer().flip();

        int written = 0;
        NioEndpoint.KeyAttachment att =
                (NioEndpoint.KeyAttachment) channel.getAttachment();
        if (att == null) {
            throw new IOException("Key must be cancelled");
        }
        long writeTimeout = att.getWriteTimeout();
        Selector selector = null;
        try {
            selector = pool.get();
        } catch ( IOException x ) {
            //ignore
        }
        try {
            written = pool.write(channel.getBufHandler().getWriteBuffer(),
                    channel, selector, writeTimeout, block);
        } finally {
            if (selector != null) {
                pool.put(selector);
            }
        }
        if (written < len) {
            channel.getPoller().add(channel, SelectionKey.OP_WRITE);
        }
        return written;
    }


    @Override
    protected void doFlush() throws IOException {
        NioEndpoint.KeyAttachment att =
                (NioEndpoint.KeyAttachment) channel.getAttachment();
        if (att == null) {
            throw new IOException("Key must be cancelled");
        }
        long writeTimeout = att.getWriteTimeout();
        Selector selector = null;
        try {
            selector = pool.get();
        } catch ( IOException x ) {
            //ignore
        }
        try {
            do {
                if (channel.flush(true, selector, writeTimeout)) {
                    break;
                }
            } while (true);
        } finally {
            if (selector != null) {
                pool.put(selector);
            }
        }
    }


    @Override
    protected void doClose() throws IOException {
        channel.close(true);
    }
}
