#include "curl_utils.h"
#include <chrono>

// 回调函数，用于处理从服务器接收到的数据
size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) {
	size_t totalSize = size * nmemb;
	userp->append((char*)contents, totalSize);
	return totalSize;
}

// 回调函数，用于处理接收到的响应头
size_t HeaderCallback(char* buffer, size_t size, size_t nitems, void* userdata) {
	HeaderData* headerData = static_cast<HeaderData*>(userdata);
	std::string header(buffer, size * nitems);
	if (!headerData->found && header.find("x-csrf-token:") == 0) {
		size_t colonPos = header.find(':');
		if (colonPos != std::string::npos) {
			headerData->value = header.substr(colonPos + 1);
			headerData->value.erase(0, headerData->value.find_first_not_of(" \t"));
			headerData->value.erase(headerData->value.length() - 2);
			headerData->found = true; // 标记为已找到
		}
	}

	return size * nitems;
}

vector<string> split_regex(const string& str, const string& pattern) {
	vector<string> tokens;
	regex rgx(pattern);
	sregex_token_iterator iter(str.begin(), str.end(), rgx, -1);
	sregex_token_iterator end;
	while (iter != end) {
		tokens.push_back(*iter++);
	}
	return tokens;
}

string URLEncodeFTPPath(const std::string& path) {
	CURL* curl = curl_easy_init();
	if (!curl) return path;

	std::string result;
	std::string encoded_part;

	// 分割路径，分别编码每个部分
	size_t start = 0;
	size_t end = path.find('/');

	while (end != std::string::npos) {
		std::string part = path.substr(start, end - start);
		if (!part.empty()) {
			char* encoded = curl_easy_escape(curl, part.c_str(), part.length());
			if (encoded) {
				result += encoded;
				curl_free(encoded);
			}
			else {
				result += part;
			}
		}
		result += '/';
		start = end + 1;
		end = path.find('/', start);
	}

	// 最后一部分
	if (start < path.length()) {
		std::string part = path.substr(start);
		char* encoded = curl_easy_escape(curl, part.c_str(), part.length());
		if (encoded) {
			result += encoded;
			curl_free(encoded);
		}
		else {
			result += part;
		}
	}

	curl_easy_cleanup(curl);
	return result;
}

// 写入回调函数（用于上传文件）
size_t read_callback(void* ptr, size_t size, size_t nmemb, FILE* stream) {
	size_t retcode = fread(ptr, size, nmemb, stream);
	return retcode;
}

int sendFileByFtp(string ftp_url, string file_path, string file_dir, string user, string pwd)
{
	int result = 0;
	CURL* curl;
	CURLcode res;

	// 初始化libcurl
	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();

	if (curl) {
		string encoded_ftp_url = URLEncodeFTPPath(ftp_url);
		// 1. 创建远程目录
		curl_easy_setopt(curl, CURLOPT_URL, encoded_ftp_url.c_str());
		curl_easy_setopt(curl, CURLOPT_USERNAME, user.c_str());
		curl_easy_setopt(curl, CURLOPT_PASSWORD, pwd.c_str());
		curl_easy_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS, CURLFTP_CREATE_DIR);

		// 重要：对于非标准端口，可能需要额外设置
		curl_easy_setopt(curl, CURLOPT_FTPPORT, "-");  // 被动模式
		curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L);  // 禁用 EPSV

		// 启用详细日志查看具体问题
		curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

		// 设置超时
		curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);

		// 执行目录创建
		res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			WriteLog("FTP 创建目录失: %s (错误: %d)\n",
				curl_easy_strerror(res), res);
			result = 1;
			goto end;
		}

		// 2. 上传文件到新目录
		FILE* file = nullptr;
		errno_t err = fopen_s(&file, file_path.c_str(), "rb");
		if (err != 0 || file == nullptr) {
			// 处理错误
			WriteLog("无法打开本地文件>%s\n", file_path.c_str());
			result = 1;
			goto end;
		}
		//FILE* file = fopen(file_path.c_str(), "rb");
		//if (!file) {
		//	WriteLog("无法打开本地文件>%s\n", file_path.c_str());
		//	result = 1;
		//	goto end;
		//}

		// 设置FTP上传选项
		curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
		curl_easy_setopt(curl, CURLOPT_URL, file_dir.c_str());
		curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
		curl_easy_setopt(curl, CURLOPT_READDATA, file);

		// 获取文件大小
		fseek(file, 0, SEEK_END);
		curl_off_t file_size = ftell(file);
		fseek(file, 0, SEEK_SET);
		curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, file_size);

		// 执行文件上传
		res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			WriteLog("上传文件失败:%s\n", curl_easy_strerror(res));
			result = 1;
		}
		else {
			WriteLog("文件上传成功\n");
		}

		fclose(file);
		curl_easy_cleanup(curl);
	}

end:
	curl_global_cleanup();
	return result;
}

string postJSON(string url, string body, long& http_code, string& error)
{
	string response_data = "";
	CURL* curl;
	CURLcode res;
	// 初始化 libcurl 会话
	curl_global_init(CURL_GLOBAL_DEFAULT);
	curl = curl_easy_init();

	if (curl) {
		// 设置要访问的 URL
		curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
		curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "http");
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

		// 设置请求头
		struct curl_slist* headers = NULL;
		headers = curl_slist_append(headers, "Content-Type: application/json; charset=UTF-8");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size());

		// 设置回调函数以接收响应数据
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);

		// 执行请求
		res = curl_easy_perform(curl);

		// 检查错误
		if (res != CURLE_OK)
		{
			error = curl_easy_strerror(res);

		}
		curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
		// 清理资源
		curl_slist_free_all(headers);
		curl_easy_cleanup(curl);
	}
	// 清理全局环境
	curl_global_cleanup();

	return response_data;
}