/** @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;
  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();
}
