#pragma once
#include <ssl_stream.h>
#include <event2/event.h>
#include <tfe_future.h>
#include <tfe_types.h>

enum ssl_stream_error
{
	SSL_STREAM_R_NO_ERROR=0,
	SSL_STREAM_R_SERVER_CLOSED,
	SSL_STREAM_R_CLIENT_CLOSED,
	SSL_STREAM_R_CONNECT_SERVER_TIMEOUT,
	SSL_STREAM_R_CONNECT_CLIENT_TIMEOUT,
	SSL_STREAM_R_SERVER_PROTOCOL_ERROR,
	SSL_STREAM_R_CLIENT_PROTOCOL_ERROR,
	__SSL_STREAM_R_MAX
};


struct ssl_mgr;

struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, struct event_base * ev_base_gc,
	struct key_keeper * key_keeper, void * logger);
void ssl_manager_set_new_upstream_cb(struct ssl_mgr * mgr, ssl_stream_new_hook* new_upstream_cb, void* u_para);
void ssl_manager_destroy(struct ssl_mgr * mgr);
unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir dir, struct ssl_mgr* mgr);
void ssl_stream_process_error(struct ssl_stream * s_stream, unsigned long sslerr, struct ssl_mgr* mgr);
const char* ssl_stream_get_error_string(enum ssl_stream_error error);
void ssl_stream_set_cmsg_string(struct ssl_stream *stream, enum tfe_cmsg_tlv_type type, const char *value_str);
void ssl_stream_process_zero_eof(struct ssl_stream *s_stream, struct ssl_mgr *mgr);

enum ssl_stream_action ssl_upstream_create_result_release_action(future_result_t * result);
struct ssl_stream * ssl_upstream_create_result_release_stream(future_result_t * result);
struct bufferevent * ssl_upstream_create_result_release_bev(future_result_t * result);
void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, evutil_socket_t fd_upstream,
	evutil_socket_t fd_downstream, struct tfe_stream* tcp_stream);




struct ssl_stream * ssl_downstream_create_result_release_stream(future_result_t * result);
struct bufferevent * ssl_downstream_create_result_release_bev(future_result_t * result);
void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct ssl_stream * upstream,
	evutil_socket_t fd_downstream, struct tfe_stream* tcp_stream);


void ssl_stream_free(struct ssl_stream * s_stream, struct event_base * evbase, struct bufferevent * bev);
const char* ssl_stream_dump_info(struct ssl_stream *stream, char* buffer, size_t sz);
//Follow functions are allowed to call during runtime.
int ssl_manager_add_trust_ca(struct ssl_mgr* mgr, const char* pem_file);
int ssl_manager_del_trust_ca(struct ssl_mgr* mgr, const char* pem_file);
int ssl_manager_add_crl(struct ssl_mgr* mgr, const char* pem_file);
int ssl_manager_del_crl(struct ssl_mgr* mgr, const char* pem_file);
void ssl_manager_reset_trust_ca(struct ssl_mgr* mgr);
void ssl_manager_reset_trust_ca_finish(struct ssl_mgr *mgr);
