/** @file

  Http2CommonSession.h

  @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 <unordered_set>

#include "proxy/http2/HTTP2.h"
#include "proxy/ProxySession.h"
#include "proxy/http2/Http2ConnectionState.h"
#include "proxy/http2/Http2Frame.h"

// Name                       Edata                 Description
// HTTP2_SESSION_EVENT_INIT   Http2CommonSession *  HTTP/2 session is born
// HTTP2_SESSION_EVENT_FINI   Http2CommonSession *  HTTP/2 session is ended
// HTTP2_SESSION_EVENT_RECV   Http2Frame *          Received a frame
// HTTP2_SESSION_EVENT_PRIO   Http2Frame *          Send this priority frame
// HTTP2_SESSION_EVENT_DATA   Http2Frame *          Send the data frames in the stream
// HTTP2_SESSION_EVENT_XMIT   Http2CommonSession *  Try retransmitting frames.

#define HTTP2_SESSION_EVENT_INIT          (HTTP2_SESSION_EVENTS_START + 1)
#define HTTP2_SESSION_EVENT_FINI          (HTTP2_SESSION_EVENTS_START + 2)
#define HTTP2_SESSION_EVENT_RECV          (HTTP2_SESSION_EVENTS_START + 3)
#define HTTP2_SESSION_EVENT_PRIO          (HTTP2_SESSION_EVENTS_START + 4)
#define HTTP2_SESSION_EVENT_DATA          (HTTP2_SESSION_EVENTS_START + 5)
#define HTTP2_SESSION_EVENT_XMIT          (HTTP2_SESSION_EVENTS_START + 6)
#define HTTP2_SESSION_EVENT_SHUTDOWN_INIT (HTTP2_SESSION_EVENTS_START + 7)
#define HTTP2_SESSION_EVENT_SHUTDOWN_CONT (HTTP2_SESSION_EVENTS_START + 8)
#define HTTP2_SESSION_EVENT_REENABLE      (HTTP2_SESSION_EVENTS_START + 9)
#define HTTP2_SESSION_EVENT_ERROR         (HTTP2_SESSION_EVENTS_START + 10)

enum class Http2SessionCod : int {
  NOT_PROVIDED,
  HIGH_ERROR_RATE,
};

enum class Http2SsnMilestone {
  OPEN = 0,
  CLOSE,
  LAST_ENTRY,
};

#if TS_USE_MALLOC_ALLOCATOR
size_t const HTTP2_HEADER_BUFFER_SIZE_INDEX = BUFFER_SIZE_INDEX_FOR_XMALLOC_SIZE(4096);
#else
size_t const HTTP2_HEADER_BUFFER_SIZE_INDEX = BUFFER_SIZE_INDEX_4K;
#endif

/**
   @startuml
   title HTTP/2 Session Handler - state of reading HTTP/2 frame
   hide empty description

   [*]                           --> state_read_connection_preface : start()
   state_read_connection_preface --> state_start_frame_read        : receive connection preface
   state_start_frame_read        --> state_start_frame_read        : do_complete_frame_read()
   state_start_frame_read        --> state_complete_frame_read     : reading HTTP/2 frame is halfway but no data in the buffer
   state_complete_frame_read     --> state_start_frame_read        : do_complete_frame_read()

   @enduml
 */
class Http2CommonSession
{
public:
  using SessionHandler = int (Http2CommonSession::*)(int, void *);

  virtual ~Http2CommonSession() = default;

  /////////////////////
  // Methods

  bool    common_free(ProxySession *ssn);
  void    write_reenable();
  int64_t xmit(const Http2TxFrame &frame, bool flush = true);
  void    flush();

  int64_t          get_connection_id();
  Ptr<ProxyMutex> &get_mutex();
  NetVConnection  *get_netvc();
  void             do_clear_session_active();

  ////////////////////
  // Accessors
  void         set_dying_event(int event);
  int          get_dying_event() const;
  bool         ready_to_free() const;
  bool         is_recursing() const;
  virtual void set_half_close_local_flag(bool flag);
  bool         get_half_close_local_flag() const;
  bool         is_url_pushed(const char *url, int url_len);
  void         add_url_to_pushed_table(const char *url, int url_len);

  // Record history from Http2ConnectionState
  void remember(const SourceLocation &location, int event, int reentrant = NO_REENTRANT);

  int64_t write_avail();
  bool    is_write_high_water() const;

  virtual ProxySession *get_proxy_session() = 0;

  virtual void add_session();
  virtual bool is_outbound() const;

  virtual void set_no_activity_timeout() = 0;

  void interrupt_reading_frames();

  ///////////////////
  // Variables
  Http2ConnectionState connection_state;

protected:
  // SessionHandler(s) - state of reading frame
  int state_read_connection_preface(int, void *);
  int state_start_frame_read(int, void *);
  int state_complete_frame_read(int, void *);

  // state_start_frame_read and state_complete_frame_read are set up as session event handler.
  // Both feed into do_process_frame_read which may iterate if there are multiple frames ready on the wire
  int do_process_frame_read(int event, VIO *vio, bool inside_frame);
  int do_start_frame_read(Http2ErrorCode &ret_error);
  int do_complete_frame_read();

  /**
   * Count received frames
   */
  void _count_received_frames(uint32_t type);

  bool _should_do_something_else();

  ////////
  // Variables
  SessionHandler session_handler = nullptr;

  MIOBuffer      *read_buffer         = nullptr;
  IOBufferReader *_read_buffer_reader = nullptr;

  VIO            *write_vio            = nullptr;
  MIOBuffer      *write_buffer         = nullptr;
  IOBufferReader *_write_buffer_reader = nullptr;

  Http2FrameHeader current_hdr              = {0, 0, 0, 0};
  uint32_t         _write_size_threshold    = 0;
  uint32_t         _write_time_threshold    = 100;
  ink_hrtime       _write_buffer_last_flush = 0;

  History<HISTORY_DEFAULT_SIZE>                                                     _history;
  Milestones<Http2SsnMilestone, static_cast<size_t>(Http2SsnMilestone::LAST_ENTRY)> _milestones;

  int             dying_event      = 0;
  bool            kill_me          = false;
  Http2SessionCod cause_of_death   = Http2SessionCod::NOT_PROVIDED;
  bool            half_close_local = false;
  int             recursion        = 0;

  std::unordered_set<std::string> *_h2_pushed_urls = nullptr;

  Event *_reenable_event = nullptr;
  int    _n_frame_read   = 0;

  uint32_t _pending_sending_data_size = 0;

  int64_t read_from_early_data      = 0;
  bool    cur_frame_from_early_data = false;

  // Counter for received frames
  std::atomic<uint64_t> _frame_counts_in[HTTP2_FRAME_TYPE_MAX + 1] = {
    0, // DATA
    0, // HEADERS
    0, // PRIORITY
    0, // RST_STREAM
    0, // SETTINGS
    0, // PUSH_PROMISE
    0, // PING
    0, // GOAWAY
    0, // WINDOW_UPDATE
    0, // CONTINUATION
    0  // UNKNOWN
  };

private:
  bool _interrupt_reading_frames = false;
};

///////////////////////////////////////////////
// INLINE

inline bool
Http2CommonSession::ready_to_free() const
{
  return kill_me;
}

inline void
Http2CommonSession::set_dying_event(int event)
{
  dying_event = event;
}

inline int
Http2CommonSession::get_dying_event() const
{
  return dying_event;
}

inline bool
Http2CommonSession::is_recursing() const
{
  return recursion > 0;
}

inline bool
Http2CommonSession::get_half_close_local_flag() const
{
  return half_close_local;
}

inline bool
Http2CommonSession::is_url_pushed(const char *url, int url_len)
{
  if (_h2_pushed_urls == nullptr) {
    return false;
  }

  return _h2_pushed_urls->find(std::string{url, static_cast<size_t>(url_len)}) != _h2_pushed_urls->end();
}

inline int64_t
Http2CommonSession::get_connection_id()
{
  return get_proxy_session()->connection_id();
}

inline Ptr<ProxyMutex> &
Http2CommonSession::get_mutex()
{
  return get_proxy_session()->mutex;
}

inline NetVConnection *
Http2CommonSession::get_netvc()
{
  return get_proxy_session()->get_netvc();
}

inline void
Http2CommonSession::do_clear_session_active()
{
  get_proxy_session()->clear_session_active();
}
