/** @file

  Http2Frame

  @section license License

  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.
 */

#pragma once

#include "iocore/eventsystem/IOBuffer.h"

#include "proxy/http2/HTTP2.h"

/**
   Incoming HTTP/2 Frame
 */
class Http2Frame
{
public:
  Http2Frame(const Http2FrameHeader &h, IOBufferReader *r, bool e = false) : _hdr(h), _ioreader(r), _from_early_data(e) {}

  // Accessor
  IOBufferReader         *reader() const;
  const Http2FrameHeader &header() const;
  bool                    is_from_early_data() const;

private:
  Http2FrameHeader _hdr;
  IOBufferReader  *_ioreader        = nullptr;
  bool             _from_early_data = false;
};

/**
   Outgoing HTTP/2 Frame
 */
class Http2TxFrame
{
public:
  Http2TxFrame(const Http2FrameHeader &h) : _hdr(h) {}
  virtual ~Http2TxFrame() {}

  // Don't allocate on heap
  void *operator new(std::size_t)   = delete;
  void *operator new[](std::size_t) = delete;

  virtual int64_t write_to(MIOBuffer *iobuffer) const = 0;

protected:
  Http2FrameHeader _hdr;
};

/**
   DATA Frame
 */
class Http2DataFrame : public Http2TxFrame
{
public:
  Http2DataFrame(Http2StreamId stream_id, uint8_t flags, IOBufferReader *r, uint32_t l)
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_DATA, flags, stream_id}), _reader(r), _payload_len(l)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  IOBufferReader *_reader      = nullptr;
  uint32_t        _payload_len = 0;
};

/**
   HEADERS Frame

   TODO: support priority info & padding using Http2HeadersParameter
 */
class Http2HeadersFrame : public Http2TxFrame
{
public:
  Http2HeadersFrame(Http2StreamId stream_id, uint8_t flags, uint8_t *h, uint32_t l)
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_HEADERS, flags, stream_id}), _hdr_block(h), _hdr_block_len(l)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  uint8_t *_hdr_block     = nullptr;
  uint32_t _hdr_block_len = 0;
};

/**
   PRIORITY Frame

   TODO: implement xmit function
 */
class Http2PriorityFrame : public Http2TxFrame
{
public:
  Http2PriorityFrame(Http2StreamId stream_id, uint8_t flags, Http2Priority p)
    : Http2TxFrame({HTTP2_PRIORITY_LEN, HTTP2_FRAME_TYPE_PRIORITY, flags, stream_id}), _params(p)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  Http2Priority _params;
};

/**
   RST_STREAM Frame
 */
class Http2RstStreamFrame : public Http2TxFrame
{
public:
  Http2RstStreamFrame(Http2StreamId stream_id, uint32_t e)
    : Http2TxFrame({HTTP2_RST_STREAM_LEN, HTTP2_FRAME_TYPE_RST_STREAM, HTTP2_FRAME_NO_FLAG, stream_id}), _error_code(e)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  uint32_t _error_code;
};

/**
   SETTINGS Frame
 */
class Http2SettingsFrame : public Http2TxFrame
{
public:
  Http2SettingsFrame(Http2StreamId stream_id, uint8_t flags) : Http2TxFrame({0, HTTP2_FRAME_TYPE_SETTINGS, flags, stream_id}) {}
  Http2SettingsFrame(Http2StreamId stream_id, uint8_t flags, Http2SettingsParameter *p, uint32_t s)
    : Http2TxFrame({static_cast<uint32_t>(HTTP2_SETTINGS_PARAMETER_LEN) * s, HTTP2_FRAME_TYPE_SETTINGS, flags, stream_id}),
      _params(p),
      _psize(s)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  Http2SettingsParameter *_params = nullptr;
  uint32_t                _psize  = 0;
};

/**
   PUSH_PROMISE Frame

   TODO: support padding
 */
class Http2PushPromiseFrame : public Http2TxFrame
{
public:
  Http2PushPromiseFrame(Http2StreamId stream_id, uint8_t flags, Http2PushPromise p, uint8_t *h, uint32_t l)
    : Http2TxFrame({l + static_cast<uint32_t>(sizeof(Http2StreamId)), HTTP2_FRAME_TYPE_PUSH_PROMISE, flags, stream_id}),
      _params(p),
      _hdr_block(h),
      _hdr_block_len(l)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  Http2PushPromise _params;
  uint8_t         *_hdr_block     = nullptr;
  uint32_t         _hdr_block_len = 0;
};

/**
   PING Frame
 */
class Http2PingFrame : public Http2TxFrame
{
public:
  Http2PingFrame(Http2StreamId stream_id, uint8_t flags, const uint8_t *data)
    : Http2TxFrame({HTTP2_PING_LEN, HTTP2_FRAME_TYPE_PING, flags, stream_id}), _opaque_data(data)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  const uint8_t *_opaque_data;
};

/**
   GOAWAY Frame

   TODO: support Additional Debug Data
 */
class Http2GoawayFrame : public Http2TxFrame
{
public:
  Http2GoawayFrame(Http2Goaway p)
    : Http2TxFrame({HTTP2_GOAWAY_LEN, HTTP2_FRAME_TYPE_GOAWAY, HTTP2_FRAME_NO_FLAG, HTTP2_CONNECTION_CONTROL_STREAM}), _params(p)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  Http2Goaway _params;
};

/**
   WINDOW_UPDATE Frame
 */
class Http2WindowUpdateFrame : public Http2TxFrame
{
public:
  Http2WindowUpdateFrame(Http2StreamId stream_id, uint32_t w)
    : Http2TxFrame({HTTP2_WINDOW_UPDATE_LEN, HTTP2_FRAME_TYPE_WINDOW_UPDATE, HTTP2_FRAME_NO_FLAG, stream_id}), _window(w)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  uint32_t _window = 0;
};

/**
   CONTINUATION Frame
 */
class Http2ContinuationFrame : public Http2TxFrame
{
public:
  Http2ContinuationFrame(Http2StreamId stream_id, uint8_t flags, uint8_t *h, uint32_t l)
    : Http2TxFrame({l, HTTP2_FRAME_TYPE_CONTINUATION, flags, stream_id}), _hdr_block(h), _hdr_block_len(l)
  {
  }

  int64_t write_to(MIOBuffer *iobuffer) const override;

private:
  uint8_t *_hdr_block     = nullptr;
  uint32_t _hdr_block_len = 0;
};
