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

import java.nio.ByteBuffer;

import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/**
 * <p>The FastCGI protocol exchanges <em>frames</em>.</p>
 * <pre>
 * struct frame {
 *     ubyte version;
 *     ubyte type;
 *     ushort requestId;
 *     ushort contentLength;
 *     ubyte paddingLength;
 *     ubyte reserved;
 *     ubyte[] content;
 *     ubyte[] padding;
 * }
 * </pre>
 * <p>Depending on the {@code type}, the content may have a different format,
 * so there are specialized content parsers.</p>
 *
 * @see HeaderParser
 * @see ContentParser
 */
public abstract class Parser
{
    private static final Logger LOG = Log.getLogger(Parser.class);

    protected final HeaderParser headerParser = new HeaderParser();
    private State state = State.HEADER;
    private int padding;

    /**
     * @param buffer the bytes to parse
     * @return true if the caller should stop parsing, false if the caller should continue parsing
     */
    public boolean parse(ByteBuffer buffer)
    {
        while (true)
        {
            switch (state)
            {
                case HEADER:
                {
                    if (!headerParser.parse(buffer))
                        return false;
                    state = State.CONTENT;
                    break;
                }
                case CONTENT:
                {
                    ContentParser contentParser = findContentParser(headerParser.getFrameType());
                    if (headerParser.getContentLength() == 0)
                    {
                        contentParser.noContent();
                    }
                    else
                    {
                        ContentParser.Result result = contentParser.parse(buffer);
                        if (LOG.isDebugEnabled())
                            LOG.debug("Parsed request {} content {} result={}", headerParser.getRequest(), headerParser.getFrameType(), result);

                        if (result == ContentParser.Result.PENDING)
                        {
                            // Not enough data, signal to read/parse more.
                            return false;
                        }
                        if (result == ContentParser.Result.ASYNC)
                        {
                            // The content will be processed asynchronously, signal to stop
                            // parsing; the async operation will eventually resume parsing.
                            return true;
                        }
                    }
                    padding = headerParser.getPaddingLength();
                    state = State.PADDING;
                    break;
                }
                case PADDING:
                {
                    if (buffer.remaining() >= padding)
                    {
                        buffer.position(buffer.position() + padding);
                        reset();
                        break;
                    }
                    else
                    {
                        padding -= buffer.remaining();
                        buffer.position(buffer.limit());
                        return false;
                    }
                }
                default:
                {
                    throw new IllegalStateException();
                }
            }
        }
    }

    protected abstract ContentParser findContentParser(FCGI.FrameType frameType);

    private void reset()
    {
        headerParser.reset();
        state = State.HEADER;
        padding = 0;
    }

    public interface Listener
    {
        public void onHeader(int request, HttpField field);

        public void onHeaders(int request);

        /**
         * @param request the request id
         * @param stream the stream type
         * @param buffer the content bytes
         * @return true to signal to the parser to stop parsing, false to continue parsing
         * @see Parser#parse(java.nio.ByteBuffer)
         */
        public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer);

        public void onEnd(int request);

        public void onFailure(int request, Throwable failure);

        public static class Adapter implements Listener
        {
            @Override
            public void onHeader(int request, HttpField field)
            {
            }

            @Override
            public void onHeaders(int request)
            {
            }

            @Override
            public boolean onContent(int request, FCGI.StreamType stream, ByteBuffer buffer)
            {
                return false;
            }

            @Override
            public void onEnd(int request)
            {
            }

            @Override
            public void onFailure(int request, Throwable failure)
            {

            }
        }
    }

    private enum State
    {
        HEADER, CONTENT, PADDING
    }
}
