#pragma once
#include "util.h"

#include "openssl\bio.h"
#include "openssl\ssl.h"
#include "openssl\err.h"

class CLASS_DECLSPEC HttpsClient
{
public:
	HttpsClient();
	~HttpsClient();

private:
	static LONG initialize;
	BIO *bio;
	SSL *ssl;
	SSL_CTX *ctx;
	X509 *cert;
	BIO *cbio;

	int send();
	int sendfile(std::ifstream& infile, std::string filename, void(CALLBACK *callback)(INT64) = NULL);
	std::string ReadLine();

	static HANDLE *lock_cs;
	static void thread_setup(void);
	static void thread_cleanup(void);
	static void my_locking_callback(int mode, int type, const char *file, int line);
public:
	std::vector<char> buffer;
	struct {
		std::string line;
		std::string URI;
		std::multimap<std::string, std::string> header;
		std::map<std::string, std::string> query;
		std::vector<char> body;
	} request;
	struct {
		std::string line;
		int code;
		std::string reason;
		std::multimap<std::string, std::string> header;
		std::vector<char> body;
	} response;

	int AddHeader(std::string key, std::string value);
	std::string GetResponseHeader(std::string key);

	int GET(std::string URI);
	int POST(std::string URI);
	int POST(std::string URI, std::map<std::string,std::string> formdata);
	int POSTfile(std::string URI, std::map<std::string, std::string> formdata, std::wstring filename, void(CALLBACK *callback)(INT64) = NULL);
	int _DELETE(std::string URI);
	int _DELETE(std::string URI, std::map<std::string, std::string> formdata);

	int Print();
	int Clear();
	void Reset() { if (bio) BIO_reset(bio); }
	void Abort() { if (ssl) SSL_shutdown(ssl); }
};
