/*
 * Copyright (c) 2017 Cisco and/or its affiliates.
 * Licensed 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.
 */

#ifndef SRC_VNET_SESSION_APPLICATION_H_
#define SRC_VNET_SESSION_APPLICATION_H_

#include <vnet/session/session.h>
#include <vnet/session/segment_manager.h>
#include <vnet/session/application_namespace.h>

#define APP_DEBUG 0

#if APP_DEBUG > 0
#define APP_DBG(_fmt, _args...) clib_warning (_fmt, ##_args)
#else
#define APP_DBG(_fmt, _args...)
#endif

typedef struct _stream_session_cb_vft
{
  /** Notify server of new segment */
  int (*add_segment_callback) (u32 api_client_index,
			       const ssvm_private_t * ssvm_seg);
  /** Notify server of new segment */
  int (*del_segment_callback) (u32 api_client_index,
			       const ssvm_private_t * ssvm_seg);

  /** Notify server of newly accepted session */
  int (*session_accept_callback) (stream_session_t * new_session);

  /** Connection request callback */
  int (*session_connected_callback) (u32 app_wrk_index, u32 opaque,
				     stream_session_t * s, u8 code);

  /** Notify app that session is closing */
  void (*session_disconnect_callback) (stream_session_t * s);

  /** Notify app that session was reset */
  void (*session_reset_callback) (stream_session_t * s);

  /** Direct RX callback for built-in application */
  int (*builtin_app_rx_callback) (stream_session_t * session);

  /** Direct TX callback for built-in application */
  int (*builtin_app_tx_callback) (stream_session_t * session);

} session_cb_vft_t;

typedef struct app_worker_
{
  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);

  /** Worker index in global worker pool*/
  u32 wrk_index;

  /** Worker index in app's map pool */
  u32 wrk_map_index;

  /** Index of owning app */
  u32 app_index;

  /** Application listens for events on this svm queue */
  svm_msg_q_t *event_queue;

  /** Segment manager used for outgoing connects issued by the app */
  u32 connects_seg_manager;

  /** Lookup tables for listeners. Value is segment manager index */
  uword *listeners_table;

  /**
   * First segment manager has in the the first segment the application's
   * event fifo. Depending on what the app does, it may be either used for
   * a listener or for connects.
   */
  u32 first_segment_manager;
  u8 first_segment_manager_in_use;

  /*
   * Local "cut through" connections specific
   */

  /** Segment manager used for incoming "cut through" connects */
  u32 local_segment_manager;

  /** Pool of local sessions the app owns (as a server) */
  local_session_t *local_sessions;

  /** Hash table of the app's local connects */
  uword *local_connects;

  u8 app_is_builtin;
} app_worker_t;

typedef struct app_worker_map_
{
  u32 wrk_index;
} app_worker_map_t;

typedef struct app_listener_
{
  clib_bitmap_t *workers;	/**< workers accepting connections */
  u32 accept_rotor;		/**< last worker to accept a connection */
  u32 al_index;
} app_listener_t;

typedef struct application_
{
  /** App index in app pool */
  u32 app_index;

  /** Binary API connection index, ~0 if internal */
  u32 api_client_index;

  /** Flags */
  u32 flags;

  /** Callbacks: shoulder-taps for the server/client */
  session_cb_vft_t cb_fns;

  /** Segment manager properties. Shared by all segment managers */
  segment_manager_properties_t sm_properties;

  /** Pool of mappings that keep track of workers associated to this app */
  app_worker_map_t *worker_maps;

  /** Name registered by builtin apps */
  u8 *name;

  /** Namespace the application belongs to */
  u32 ns_index;

  u16 proxied_transports;

  /** Pool of listeners for the app */
  app_listener_t *listeners;

  /** Pool of local listeners for app */
  app_listener_t *local_listeners;

  /** Pool of local listen sessions */
  local_session_t *local_listen_sessions;

  /*
   * TLS Specific
   */

  /** Certificate to be used for listen sessions */
  u8 *tls_cert;

  /** PEM encoded key */
  u8 *tls_key;

  /** Preferred tls engine */
  u8 tls_engine;

} application_t;

typedef struct app_main_
{
  /**
   * Pool from which we allocate all applications
   */
  application_t *app_pool;

  /**
   * Pool of workers associated to apps
   */
  app_worker_t *workers;

  /**
   * Hash table of apps by api client index
   */
  uword *app_by_api_client_index;

  /**
   * Hash table of builtin apps by name
   */
  uword *app_by_name;
} app_main_t;

#define foreach_app_init_args			\
  _(u32, api_client_index)			\
  _(u8 *, name)					\
  _(u64 *, options)				\
  _(u8 *, namespace_id)				\
  _(session_cb_vft_t *, session_cb_vft)		\
  _(u32, app_index)				\

typedef struct app_init_args_
{
#define _(_type, _name) _type _name;
  foreach_app_init_args
#undef _
} app_init_args_t;

typedef struct _vnet_app_worker_add_del_args
{
  u32 app_index;		/**< App for which a new worker is requested */
  u32 wrk_index;		/**< Index to delete or return value if add */
  ssvm_private_t *segment;	/**< First segment in segment manager */
  svm_msg_q_t *evt_q;		/**< Worker message queue */
  u8 is_add;			/**< Flag set if addition */
} vnet_app_worker_add_del_args_t;

#define APP_INVALID_INDEX ((u32)~0)
#define APP_NS_INVALID_INDEX ((u32)~0)
#define APP_INVALID_SEGMENT_MANAGER_INDEX ((u32) ~0)

app_worker_t *app_worker_alloc (application_t * app);
int app_worker_alloc_and_init (application_t * app, app_worker_t ** wrk);
app_worker_t *app_worker_get (u32 wrk_index);
app_worker_t *app_worker_get_if_valid (u32 wrk_index);
application_t *app_worker_get_app (u32 wrk_index);
void app_worker_free (app_worker_t * app_wrk);
int app_worker_open_session (app_worker_t * app, session_endpoint_t * tep,
			     u32 api_context);
segment_manager_t *app_worker_get_listen_segment_manager (app_worker_t *,
							  stream_session_t *);
segment_manager_t *app_worker_get_connect_segment_manager (app_worker_t *);
int app_worker_alloc_connects_segment_manager (app_worker_t * app);
int app_worker_add_segment_notify (u32 app_or_wrk, ssvm_private_t * fs);
u32 app_worker_n_listeners (app_worker_t * app);
stream_session_t *app_worker_first_listener (app_worker_t * app,
					     u8 fib_proto,
					     u8 transport_proto);
u8 app_worker_application_is_builtin (app_worker_t * app_wrk);
int app_worker_send_event (app_worker_t * app, stream_session_t * s, u8 evt);
int app_worker_lock_and_send_event (app_worker_t * app, stream_session_t * s,
				    u8 evt_type);
clib_error_t *vnet_app_worker_add_del (vnet_app_worker_add_del_args_t * a);

int application_start_listen (application_t * app,
			      session_endpoint_cfg_t * tep,
			      session_handle_t * handle);
int application_stop_listen (u32 app_index, u32 app_or_wrk,
			     session_handle_t handle);

application_t *application_alloc (void);
int application_alloc_and_init (app_init_args_t * args);
void application_free (application_t * app);
application_t *application_get (u32 index);
application_t *application_get_if_valid (u32 index);
application_t *application_lookup (u32 api_client_index);
application_t *application_lookup_name (const u8 * name);
u32 application_index (application_t * app);
app_worker_t *application_get_worker (application_t * app, u32 wrk_index);
app_worker_t *application_get_default_worker (application_t * app);
app_worker_t *application_listener_select_worker (stream_session_t * ls,
						  u8 is_local);

int application_api_queue_is_full (application_t * app);

int application_is_proxy (application_t * app);
int application_is_builtin (application_t * app);
int application_is_builtin_proxy (application_t * app);
u32 application_session_table (application_t * app, u8 fib_proto);
u32 application_local_session_table (application_t * app);
u8 *application_name_from_index (u32 app_or_wrk);
u8 application_has_local_scope (application_t * app);
u8 application_has_global_scope (application_t * app);
u8 application_use_mq_for_ctrl (application_t * app);
void application_setup_proxy (application_t * app);
void application_remove_proxy (application_t * app);

segment_manager_properties_t *application_get_segment_manager_properties (u32
									  app_index);

segment_manager_properties_t
  * application_segment_manager_properties (application_t * app);

/*
 * Local session
 */

local_session_t *application_local_session_alloc (app_worker_t * app);
void application_local_session_free (app_worker_t * app,
				     local_session_t * ls);
local_session_t *application_get_local_session (app_worker_t * app,
						u32 session_index);
local_session_t *application_get_local_session_from_handle (session_handle_t
							    handle);
local_session_t
  * application_get_local_listen_session_from_handle (session_handle_t lh);
int application_start_local_listen (application_t * server,
				    session_endpoint_cfg_t * sep,
				    session_handle_t * handle);
int application_stop_local_listen (u32 app_index, u32 app_or_wrk,
				   session_handle_t lh);
int application_local_session_connect (app_worker_t * client,
				       app_worker_t * server,
				       local_session_t * ls, u32 opaque);
int application_local_session_connect_notify (local_session_t * ls);
int application_local_session_disconnect (u32 app_or_wrk,
					  local_session_t * ls);
int application_local_session_disconnect_w_index (u32 app_or_wrk,
						  u32 ls_index);
void app_worker_local_sessions_free (app_worker_t * app);

always_inline u32
local_session_id (local_session_t * ls)
{
  ASSERT (ls->session_index < (2 << 16));
  u32 app_or_wrk_index;

  if (ls->session_state == SESSION_STATE_LISTENING)
    {
      ASSERT (ls->app_index < (2 << 16));
      app_or_wrk_index = ls->app_index;
    }
  else
    {
      ASSERT (ls->app_wrk_index < (2 << 16));
      app_or_wrk_index = ls->app_wrk_index;
    }

  return ((u32) app_or_wrk_index << 16 | (u32) ls->session_index);
}

always_inline void
local_session_parse_id (u32 ls_id, u32 * app_or_wrk, u32 * session_index)
{
  *app_or_wrk = ls_id >> 16;
  *session_index = ls_id & 0xFF;
}

always_inline void
local_session_parse_handle (session_handle_t handle, u32 * app_or_wrk_index,
			    u32 * session_index)
{
  u32 bottom;
  ASSERT ((handle >> 32) == SESSION_LOCAL_HANDLE_PREFIX);
  bottom = (handle & 0xFFFFFFFF);
  local_session_parse_id (bottom, app_or_wrk_index, session_index);
}

always_inline session_handle_t
application_local_session_handle (local_session_t * ls)
{
  return ((u64) SESSION_LOCAL_HANDLE_PREFIX << 32)
    | (u64) local_session_id (ls);
}

always_inline local_session_t *
application_get_local_listen_session (application_t * app, u32 session_index)
{
  return pool_elt_at_index (app->local_listen_sessions, session_index);
}

always_inline local_session_t *
application_get_local_listener_w_handle (session_handle_t handle)
{
  u32 server_index, session_index;
  application_t *app;
  local_session_parse_handle (handle, &server_index, &session_index);
  app = application_get (server_index);
  return application_get_local_listen_session (app, session_index);
}

always_inline u8
application_local_session_listener_has_transport (local_session_t * ls)
{
  transport_proto_t tp;
  tp = session_type_transport_proto (ls->listener_session_type);
  return (tp != TRANSPORT_PROTO_NONE);
}

void mq_send_local_session_disconnected_cb (u32 app_or_wrk,
					    local_session_t * ls);

uword unformat_application_proto (unformat_input_t * input, va_list * args);

#endif /* SRC_VNET_SESSION_APPLICATION_H_ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
