//
//  ========================================================================
//  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.spdy;

import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.spdy.api.DataInfo;
import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.frames.WindowUpdateFrame;
import org.eclipse.jetty.util.Callback;

public class SPDYv3FlowControlStrategy implements FlowControlStrategy
{
    private volatile int windowSize;

    @Override
    public int getWindowSize(ISession session)
    {
        return windowSize;
    }

    @Override
    public void setWindowSize(ISession session, int windowSize)
    {
        int prevWindowSize = this.windowSize;
        this.windowSize = windowSize;
        for (Stream stream : session.getStreams())
            ((IStream)stream).updateWindowSize(windowSize - prevWindowSize);
    }

    @Override
    public void onNewStream(ISession session, IStream stream)
    {
        stream.updateWindowSize(windowSize);
    }

    @Override
    public void onWindowUpdate(ISession session, IStream stream, int delta)
    {
        if (stream != null)
            stream.updateWindowSize(delta);
    }

    @Override
    public void updateWindow(ISession session, IStream stream, int delta)
    {
        stream.updateWindowSize(delta);
    }

    @Override
    public void onDataReceived(ISession session, IStream stream, DataInfo dataInfo)
    {
        // Do nothing
    }

    @Override
    public void onDataConsumed(ISession session, IStream stream, DataInfo dataInfo, int delta)
    {
        // This is the algorithm for flow control.
        // This method may be called multiple times with delta=1, but we only send a window
        // update when the whole dataInfo has been consumed.
        // Other policies may be to send window updates when consumed() is greater than
        // a certain threshold, etc. but for now the policy is not pluggable for simplicity.
        // Note that the frequency of window updates depends on the read buffer, that
        // should not be too smaller than the window size to avoid frequent window updates.
        // Therefore, a pluggable policy should be able to modify the read buffer capacity.
        int length = dataInfo.length();
        if (dataInfo.consumed() == length && !stream.isClosed() && length > 0)
        {
            WindowUpdateFrame windowUpdateFrame = new WindowUpdateFrame(session.getVersion(), stream.getId(), length);
            session.control(stream, windowUpdateFrame, 0, TimeUnit.MILLISECONDS, Callback.Adapter.INSTANCE);
        }
    }
}
