<commit_before>#include "websocket.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "cJSON.h"

#include "signal.h"

int client_ws_receive_callback(client_websocket_t *socket, char *data, size_t length);
int client_ws_connection_error_callback(client_websocket_t* socket, char* reason, size_t length);
void *heartbeatFunction(void *websocket);

void handleEventDispatch(client_websocket_t *socket, cJSON *root);
void handleIdentify(client_websocket_t *socket);
void handleOnReady(client_websocket_t *socket, cJSON *root);
void handleGuildMemberChunk(cJSON *root);

/*
// Cleanup
void freeServers(struct server *node);
void freeChannels(struct server_channel *node);
void freeUsers(struct server_user *node);
void freeRoles(struct roles *node);
*/

// Stores the information associated with a connection (token, websocket, etc)
struct connection
{

	// TODO
};

struct user
{
	// Username
	char *username;
	// id
	uint64_t id;
	// TODO Add more fields
};

// Struct that stores a role
struct role
{
	uint64_t id;
	// TODO is uint32_t large enough?
	uint32_t position;
	uint32_t permissions;
	uint32_t color;
	
	char *name;

	// Boolean!
	uint8_t mentionable;
};

// "wrapper" object to go from role -> linked list (for users & server role list). This allows for only storing a role once, instead of potentially multiple thousands of times.
struct roles
{
	struct role *role;

	struct roles *next;
};

struct server_user
{
	// User information
	struct user *user;
	
	// TODO roles & other server specific stuff
	struct roles *roles;

	// Linked list next node
	struct server_user *next;
};

struct server_channel
{
	// Channel name
	char *name;
	// Channel topic
	char *topic;
	// Channel id
	uint64_t id;

	// Linked list next node
	struct server_channel *next;
};


struct server
{
	// Server name
	char *name;
	// Server id
	uint64_t serverId;

	// Channels
	struct server_channel *channels;
	// Users
	struct server_user *users;
	// Roles
	struct roles *roles;

	// Linked list next node
	struct server *next;
};

typedef void (*discord_login_complete_callback)(struct connection connection, struct server servers);
//typedef int (*websocket_connection_error_callback)(client_websocket_t* client, char* reason, size_t length);

struct discord_callbacks {
	discord_login_complete_callback login_complete;
//	websocket_connection_error_callback on_connection_error;
};

// Cleanup
void freeServers(struct server *node);
void freeChannels(struct server_channel *node);
void freeUsers(struct server_user *node);
void freeRoles(struct roles *node);

// Ugly global variable for CLI callbacks
struct discord_callbacks cli_callbacks;
// Even more ugly global variable that stores the servers linked list. Needed to go from server id -> server linked list in some functions :(
struct server *glob_servers = NULL;
// Super ugly global variable to store if it's currently awaiting member fragments
uint8_t isRetrievingMembers  = 0;

void sigintHandler(int sig)
{
	freeServers(glob_servers);
}

int main(int argc, char *argv[])
{
	signal(SIGINT, sigintHandler);

	printf("Websocket thing starting up!");
	client_websocket_callbacks_t myCallbacks;
	
	myCallbacks.on_receive = client_ws_receive_callback;
	myCallbacks.on_connection_error = client_ws_connection_error_callback;

	client_websocket_t *myWebSocket = malloc(sizeof(client_websocket_t));
       	myWebSocket = websocket_create(&myCallbacks);
	
	// TODO Make this grab the gateway instead of hard-coding it
	//if (argc != 2)
	websocket_connect(myWebSocket, "wss://gateway.discord.gg/?v=5&encoding=json");
	//sleep(20);
	for (int i = 0; i < 10; i++)<commit_msg>Added exit to sigkill handler<commit_after>#include "websocket.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "pthread.h"
#include "cJSON.h"

#include "signal.h"

int client_ws_receive_callback(client_websocket_t *socket, char *data, size_t length);
int client_ws_connection_error_callback(client_websocket_t* socket, char* reason, size_t length);
void *heartbeatFunction(void *websocket);

void handleEventDispatch(client_websocket_t *socket, cJSON *root);
void handleIdentify(client_websocket_t *socket);
void handleOnReady(client_websocket_t *socket, cJSON *root);
void handleGuildMemberChunk(cJSON *root);

/*
// Cleanup
void freeServers(struct server *node);
void freeChannels(struct server_channel *node);
void freeUsers(struct server_user *node);
void freeRoles(struct roles *node);
*/

// Stores the information associated with a connection (token, websocket, etc)
struct connection
{

	// TODO
};

struct user
{
	// Username
	char *username;
	// id
	uint64_t id;
	// TODO Add more fields
};

// Struct that stores a role
struct role
{
	uint64_t id;
	// TODO is uint32_t large enough?
	uint32_t position;
	uint32_t permissions;
	uint32_t color;
	
	char *name;

	// Boolean!
	uint8_t mentionable;
};

// "wrapper" object to go from role -> linked list (for users & server role list). This allows for only storing a role once, instead of potentially multiple thousands of times.
struct roles
{
	struct role *role;

	struct roles *next;
};

struct server_user
{
	// User information
	struct user *user;
	
	// TODO roles & other server specific stuff
	struct roles *roles;

	// Linked list next node
	struct server_user *next;
};

struct server_channel
{
	// Channel name
	char *name;
	// Channel topic
	char *topic;
	// Channel id
	uint64_t id;

	// Linked list next node
	struct server_channel *next;
};


struct server
{
	// Server name
	char *name;
	// Server id
	uint64_t serverId;

	// Channels
	struct server_channel *channels;
	// Users
	struct server_user *users;
	// Roles
	struct roles *roles;

	// Linked list next node
	struct server *next;
};

typedef void (*discord_login_complete_callback)(struct connection connection, struct server servers);
//typedef int (*websocket_connection_error_callback)(client_websocket_t* client, char* reason, size_t length);

struct discord_callbacks {
	discord_login_complete_callback login_complete;
//	websocket_connection_error_callback on_connection_error;
};

// Cleanup
void freeServers(struct server *node);
void freeChannels(struct server_channel *node);
void freeUsers(struct server_user *node);
void freeRoles(struct roles *node);

// Ugly global variable for CLI callbacks
struct discord_callbacks cli_callbacks;
// Even more ugly global variable that stores the servers linked list. Needed to go from server id -> server linked list in some functions :(
struct server *glob_servers = NULL;
// Super ugly global variable to store if it's currently awaiting member fragments
uint8_t isRetrievingMembers  = 0;

void sigintHandler(int sig)
{
	freeServers(glob_servers);
	exit(1);
}

int main(int argc, char *argv[])
{
	signal(SIGINT, sigintHandler);

	printf("Websocket thing starting up!");
	client_websocket_callbacks_t myCallbacks;
	
	myCallbacks.on_receive = client_ws_receive_callback;
	myCallbacks.on_connection_error = client_ws_connection_error_callback;

	client_websocket_t *myWebSocket = malloc(sizeof(client_websocket_t));
       	myWebSocket = websocket_create(&myCallbacks);
	
	// TODO Make this grab the gateway instead of hard-coding it
	//if (argc != 2)
	websocket_connect(myWebSocket, "wss://gateway.discord.gg/?v=5&encoding=json");
	//sleep(20);
	for (int i = 0; i < 10; i++)
{'fraction_non_alphanumeric': 0.09729803493449782, 'fraction_numerical': 0.0072325327510917034, 'mean_word_length': 4.973105134474328, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1715377', 'n_tokens_mistral': 2430, 'n_tokens_neox': 2303, 'n_words': 728}