#include "net/http_client.h"
#include "error.h"
#include "str.h"

#include <string.h>
#include <windows.h>
#include <wininet.h>

static HINTERNET internet = 0;

#define REQ_PROGRESS 0
#define REQ_DONE 1
#define REQ_FREE 2

struct request {
	u8 *response;
	u32 response_length;
	HINTERNET handle;
	u8 status;
};

static struct request *requests = 0;
static u32 request_count = 0;

static void init_internet();
static u32 next_free_request();

struct sw_http_request_handle sw_http_request_async(char *url) {
	HINTERNET session, http;
	u16 port = 0;
	;
	char *proto, *rest;
	char *server, *rest2;
	u32 req;

	sw_str_split2(url, "://", &proto, &rest);
	if(proto == 0) {
		sw_error("url requires ://");
	}

	if(strcmp(proto, "https") == 0) {
		port = INTERNET_DEFAULT_HTTPS_PORT;
	} else if(strcmp(proto, "http") == 0) {
		port = INTERNET_DEFAULT_HTTP_PORT;
	} else {
		sw_error("unknown protocol '%s'", proto);
	}

	sw_str_split2(url, "/", &server, &rest2);
	/* TODO: handle urls without / */

	init_internet();

	session = InternetConnect(
	    internet, server, port, 0, 0, INTERNET_SERVICE_HTTP, 0, 0
	);

	if(session == 0) {
		sw_win32_error();
	}

	http = HttpOpenRequest(session, "GET", rest2, "HTTP/1.1", 0, 0, 0, 0);

	if(http == 0) {
		sw_win32_error();
	}

	if(!HttpSendRequest(http, 0, 0, 0, 0)) {
		sw_win32_error();
	}

	req = next_free_request();
	requests[req].handle = http;

	return (struct sw_http_request_handle){req};
}

static void init_internet() {
	if(internet == 0) {
		internet = InternetOpen(
		    "Skunkworks", INTERNET_OPEN_TYPE_DIRECT, 0, 0, INTERNET_FLAG_ASYNC
		);
		if(internet == 0) {
			sw_win32_error();
		}
	}
}

static u32 next_free_request() {
	u32 i;

	for(i = 0; i < request_count; ++i) {
		if(requests[i].status == REQ_FREE) {
			return i;
		}
	}

	request_count += 1;

	requests = realloc(requests, sizeof(struct request) * request_count);

	requests[request_count - 1].handle = 0;
	requests[request_count - 1].response = 0;
	requests[request_count - 1].response_length = 0;
	requests[request_count - 1].status = REQ_PROGRESS;

	return request_count - 1;
}
