#pragma once

#include <tfe_stream.h>
#include <tfe_types.h>
#include <ssl_utils.h>
#include <event2/event.h>
#include <MESA/MESA_htable.h>

#define PINNING_ST_NOT_PINNING		0
#define PINNING_ST_PINNING			1
#define PINNING_ST_MAYBE_PINNING	2

struct ssl_service_status
{
	char cli_pinning_status;
    char ja3_pinning_status;
    char is_ev;
	char is_ct;
	char is_mutual_auth;
	char has_protocol_errors;
};
struct ssl_service_cache_statistics
{
	long long pinning_cli_cnt;
	long long mutual_auth_cli_cnt;
	long long proto_err_cli_cnt;
	long long ev_srv_cnt;
	long long ct_srv_cnt;
	long long app_not_pinning_cnt;
	long long trusted_cert_cnt;
};
struct ssl_service_cache
{
	MESA_htable_handle cli_st_hash;
	MESA_htable_handle srv_st_hash;
	
	struct ssl_service_cache_statistics stat;
	unsigned int fail_as_cli_pinning_count;
	unsigned int fail_as_proto_err_count;
	unsigned int fail_time_window;
};
struct ssl_service_cache* ssl_service_cache_create(unsigned int slot_size, unsigned int expire_seconds, int fail_as_pinning_cnt, int fail_as_proto_err_cnt, int fail_time_win, char *ja3_table_name);
void ssl_service_cache_destroy(struct ssl_service_cache* cache);

int ssl_service_cache_read(struct ssl_service_cache *svc_cache, const struct ssl_chello *chello, const struct tfe_stream *tcp_stream, struct ssl_service_status *result);
void ssl_service_cache_write(struct ssl_service_cache *svc_cache, const struct ssl_chello *chello, const struct tfe_stream *tcp_stream, const struct ssl_service_status *status);
void ssl_service_cache_stat(struct ssl_service_cache *svc_cache, struct ssl_service_cache_statistics *result);
