// Copyright (c) 2020 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=ffd489adc301ed88e1f30f8f38cec1730411a4b5$
//

#ifndef CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
#pragma once

#include "include/capi/cef_base_capi.h"
#include "include/capi/cef_callback_capi.h"
#include "include/capi/cef_request_capi.h"
#include "include/capi/cef_task_capi.h"

#ifdef __cplusplus
extern "C" {
#endif

struct _cef_server_handler_t;

///
// Structure representing a server that supports HTTP and WebSocket requests.
// Server capacity is limited and is intended to handle only a small number of
// simultaneous connections (e.g. for communicating between applications on
// localhost). The functions of this structure are safe to call from any thread
// in the brower process unless otherwise indicated.
///
typedef struct _cef_server_t {
  ///
  // Base structure.
  ///
  cef_base_ref_counted_t base;

  ///
  // Returns the task runner for the dedicated server thread.
  ///
  struct _cef_task_runner_t*(CEF_CALLBACK* get_task_runner)(
      struct _cef_server_t* self);

  ///
  // Stop the server and shut down the dedicated server thread. See
  // cef_server_handler_t::OnServerCreated documentation for a description of
  // server lifespan.
  ///
  void(CEF_CALLBACK* shutdown)(struct _cef_server_t* self);

  ///
  // Returns true (1) if the server is currently running and accepting incoming
  // connections. See cef_server_handler_t::OnServerCreated documentation for a
  // description of server lifespan. This function must be called on the
  // dedicated server thread.
  ///
  int(CEF_CALLBACK* is_running)(struct _cef_server_t* self);

  ///
  // Returns the server address including the port number.
  ///
  // The resulting string must be freed by calling cef_string_userfree_free().
  cef_string_userfree_t(CEF_CALLBACK* get_address)(struct _cef_server_t* self);

  ///
  // Returns true (1) if the server currently has a connection. This function
  // must be called on the dedicated server thread.
  ///
  int(CEF_CALLBACK* has_connection)(struct _cef_server_t* self);

  ///
  // Returns true (1) if |connection_id| represents a valid connection. This
  // function must be called on the dedicated server thread.
  ///
  int(CEF_CALLBACK* is_valid_connection)(struct _cef_server_t* self,
                                         int connection_id);

  ///
  // Send an HTTP 200 "OK" response to the connection identified by
  // |connection_id|. |content_type| is the response content type (e.g.
  // "text/html"), |data| is the response content, and |data_size| is the size
  // of |data| in bytes. The contents of |data| will be copied. The connection
  // will be closed automatically after the response is sent.
  ///
  void(CEF_CALLBACK* send_http200response)(struct _cef_server_t* self,
                                           int connection_id,
                                           const cef_string_t* content_type,
                                           const void* data,
                                           size_t data_size);

  ///
  // Send an HTTP 404 "Not Found" response to the connection identified by
  // |connection_id|. The connection will be closed automatically after the
  // response is sent.
  ///
  void(CEF_CALLBACK* send_http404response)(struct _cef_server_t* self,
                                           int connection_id);

  ///
  // Send an HTTP 500 "Internal Server Error" response to the connection
  // identified by |connection_id|. |error_message| is the associated error
  // message. The connection will be closed automatically after the response is
  // sent.
  ///
  void(CEF_CALLBACK* send_http500response)(struct _cef_server_t* self,
                                           int connection_id,
                                           const cef_string_t* error_message);

  ///
  // Send a custom HTTP response to the connection identified by
  // |connection_id|. |response_code| is the HTTP response code sent in the
  // status line (e.g. 200), |content_type| is the response content type sent as
  // the "Content-Type" header (e.g. "text/html"), |content_length| is the
  // expected content length, and |extra_headers| is the map of extra response
  // headers. If |content_length| is >= 0 then the "Content-Length" header will
  // be sent. If |content_length| is 0 then no content is expected and the
  // connection will be closed automatically after the response is sent. If
  // |content_length| is < 0 then no "Content-Length" header will be sent and
  // the client will continue reading until the connection is closed. Use the
  // SendRawData function to send the content, if applicable, and call
  // CloseConnection after all content has been sent.
  ///
  void(CEF_CALLBACK* send_http_response)(struct _cef_server_t* self,
                                         int connection_id,
                                         int response_code,
                                         const cef_string_t* content_type,
                                         int64 content_length,
                                         cef_string_multimap_t extra_headers);

  ///
  // Send raw data directly to the connection identified by |connection_id|.
  // |data| is the raw data and |data_size| is the size of |data| in bytes. The
  // contents of |data| will be copied. No validation of |data| is performed
  // internally so the client should be careful to send the amount indicated by
  // the "Content-Length" header, if specified. See SendHttpResponse
  // documentation for intended usage.
  ///
  void(CEF_CALLBACK* send_raw_data)(struct _cef_server_t* self,
                                    int connection_id,
                                    const void* data,
                                    size_t data_size);

  ///
  // Close the connection identified by |connection_id|. See SendHttpResponse
  // documentation for intended usage.
  ///
  void(CEF_CALLBACK* close_connection)(struct _cef_server_t* self,
                                       int connection_id);

  ///
  // Send a WebSocket message to the connection identified by |connection_id|.
  // |data| is the response content and |data_size| is the size of |data| in
  // bytes. The contents of |data| will be copied. See
  // cef_server_handler_t::OnWebSocketRequest documentation for intended usage.
  ///
  void(CEF_CALLBACK* send_web_socket_message)(struct _cef_server_t* self,
                                              int connection_id,
                                              const void* data,
                                              size_t data_size);
} cef_server_t;

///
// Create a new server that binds to |address| and |port|. |address| must be a
// valid IPv4 or IPv6 address (e.g. 127.0.0.1 or ::1) and |port| must be a port
// number outside of the reserved range (e.g. between 1025 and 65535 on most
// platforms). |backlog| is the maximum number of pending connections. A new
// thread will be created for each CreateServer call (the "dedicated server
// thread"). It is therefore recommended to use a different cef_server_handler_t
// instance for each CreateServer call to avoid thread safety issues in the
// cef_server_handler_t implementation. The
// cef_server_handler_t::OnServerCreated function will be called on the
// dedicated server thread to report success or failure. See
// cef_server_handler_t::OnServerCreated documentation for a description of
// server lifespan.
///
CEF_EXPORT void cef_server_create(const cef_string_t* address,
                                  uint16 port,
                                  int backlog,
                                  struct _cef_server_handler_t* handler);

///
// Implement this structure to handle HTTP server requests. A new thread will be
// created for each cef_server_t::CreateServer call (the "dedicated server
// thread"), and the functions of this structure will be called on that thread.
// It is therefore recommended to use a different cef_server_handler_t instance
// for each cef_server_t::CreateServer call to avoid thread safety issues in the
// cef_server_handler_t implementation.
///
typedef struct _cef_server_handler_t {
  ///
  // Base structure.
  ///
  cef_base_ref_counted_t base;

  ///
  // Called when |server| is created. If the server was started successfully
  // then cef_server_t::IsRunning will return true (1). The server will continue
  // running until cef_server_t::Shutdown is called, after which time
  // OnServerDestroyed will be called. If the server failed to start then
  // OnServerDestroyed will be called immediately after this function returns.
  ///
  void(CEF_CALLBACK* on_server_created)(struct _cef_server_handler_t* self,
                                        struct _cef_server_t* server);

  ///
  // Called when |server| is destroyed. The server thread will be stopped after
  // this function returns. The client should release any references to |server|
  // when this function is called. See OnServerCreated documentation for a
  // description of server lifespan.
  ///
  void(CEF_CALLBACK* on_server_destroyed)(struct _cef_server_handler_t* self,
                                          struct _cef_server_t* server);

  ///
  // Called when a client connects to |server|. |connection_id| uniquely
  // identifies the connection. Each call to this function will have a matching
  // call to OnClientDisconnected.
  ///
  void(CEF_CALLBACK* on_client_connected)(struct _cef_server_handler_t* self,
                                          struct _cef_server_t* server,
                                          int connection_id);

  ///
  // Called when a client disconnects from |server|. |connection_id| uniquely
  // identifies the connection. The client should release any data associated
  // with |connection_id| when this function is called and |connection_id|
  // should no longer be passed to cef_server_t functions. Disconnects can
  // originate from either the client or the server. For example, the server
  // will disconnect automatically after a cef_server_t::SendHttpXXXResponse
  // function is called.
  ///
  void(CEF_CALLBACK* on_client_disconnected)(struct _cef_server_handler_t* self,
                                             struct _cef_server_t* server,
                                             int connection_id);

  ///
  // Called when |server| receives an HTTP request. |connection_id| uniquely
  // identifies the connection, |client_address| is the requesting IPv4 or IPv6
  // client address including port number, and |request| contains the request
  // contents (URL, function, headers and optional POST data). Call cef_server_t
  // functions either synchronously or asynchronusly to send a response.
  ///
  void(CEF_CALLBACK* on_http_request)(struct _cef_server_handler_t* self,
                                      struct _cef_server_t* server,
                                      int connection_id,
                                      const cef_string_t* client_address,
                                      struct _cef_request_t* request);

  ///
  // Called when |server| receives a WebSocket request. |connection_id| uniquely
  // identifies the connection, |client_address| is the requesting IPv4 or IPv6
  // client address including port number, and |request| contains the request
  // contents (URL, function, headers and optional POST data). Execute
  // |callback| either synchronously or asynchronously to accept or decline the
  // WebSocket connection. If the request is accepted then OnWebSocketConnected
  // will be called after the WebSocket has connected and incoming messages will
  // be delivered to the OnWebSocketMessage callback. If the request is declined
  // then the client will be disconnected and OnClientDisconnected will be
  // called. Call the cef_server_t::SendWebSocketMessage function after
  // receiving the OnWebSocketConnected callback to respond with WebSocket
  // messages.
  ///
  void(CEF_CALLBACK* on_web_socket_request)(struct _cef_server_handler_t* self,
                                            struct _cef_server_t* server,
                                            int connection_id,
                                            const cef_string_t* client_address,
                                            struct _cef_request_t* request,
                                            struct _cef_callback_t* callback);

  ///
  // Called after the client has accepted the WebSocket connection for |server|
  // and |connection_id| via the OnWebSocketRequest callback. See
  // OnWebSocketRequest documentation for intended usage.
  ///
  void(CEF_CALLBACK* on_web_socket_connected)(
      struct _cef_server_handler_t* self,
      struct _cef_server_t* server,
      int connection_id);

  ///
  // Called when |server| receives an WebSocket message. |connection_id|
  // uniquely identifies the connection, |data| is the message content and
  // |data_size| is the size of |data| in bytes. Do not keep a reference to
  // |data| outside of this function. See OnWebSocketRequest documentation for
  // intended usage.
  ///
  void(CEF_CALLBACK* on_web_socket_message)(struct _cef_server_handler_t* self,
                                            struct _cef_server_t* server,
                                            int connection_id,
                                            const void* data,
                                            size_t data_size);
} cef_server_handler_t;

#ifdef __cplusplus
}
#endif

#endif  // CEF_INCLUDE_CAPI_CEF_SERVER_CAPI_H_
