#pragma semicolon 1

#include <sourcemod>
#include <vip_core>
#undef REQUIRE_EXTENSIONS
#include <cURL>
#include <socket>
#include <steamtools>
#include <SteamWorks>
#define REQUIRE_EXTENSIONS

#define CURL_AVAILABLE()		(GetFeatureStatus(FeatureType_Native, "curl_easy_init") == FeatureStatus_Available)
#define SOCKET_AVAILABLE()		(GetFeatureStatus(FeatureType_Native, "SocketCreate") == FeatureStatus_Available)
#define STEAMTOOLS_AVAILABLE()	(GetFeatureStatus(FeatureType_Native, "Steam_CreateHTTPRequest") == FeatureStatus_Available)
#define STEAMWORKS_AVAILABLE()	(GetFeatureStatus(FeatureType_Native, "SteamWorks_WriteHTTPResponseBodyToFile") == FeatureStatus_Available)

#define MAX_URL_LENGTH		256

public Plugin:myinfo =
{
	name = "[VIP] Updater",
	author = "R1KO (skype: vova.andrienko1)",
	version = "1.0.0"
};

#include "download_curl.sp"
#include "download_socket.sp"
#include "download_steamtools.sp"
#include "download_steamworks.sp"

static const String:g_sUPDATE_URL[]= "http://mysite.com/plugins_update/vip/update.txt";

static String:_sDataPath[PLATFORM_MAX_PATH];

static String:g_sLogFile[PLATFORM_MAX_PATH];

public OnPluginStart()
{
	if (!CURL_AVAILABLE() && !SOCKET_AVAILABLE() && !STEAMTOOLS_AVAILABLE() && !STEAMWORKS_AVAILABLE())
	{
		SetFailState("This plugin requires one of the cURL, Socket, SteamTools, or SteamWorks extensions to function.");
	}

	BuildPath(Path_SM, _sDataPath, sizeof(_sDataPath), "data/vip/modules/updater.txt");
	BuildPath(Path_SM, g_sLogFile, sizeof(g_sLogFile), "logs/VIP_Updater.log");

	ProcessDownloadQueue();
}

ProcessDownloadQueue()
{
	if (STEAMWORKS_AVAILABLE())
	{
		if (SteamWorks_IsLoaded())
		{
			Download_SteamWorks(g_sUPDATE_URL, _sDataPath);
		}
		else
		{
			CreateTimer(10.0, Timer_RetryQueue);
		}
	}
	else if (STEAMTOOLS_AVAILABLE())
	{
		if (g_bSteamLoaded)
		{
			Download_SteamTools(g_sUPDATE_URL, _sDataPath);
		}
		else
		{
			CreateTimer(10.0, Timer_RetryQueue);
		}
	}
	else if (CURL_AVAILABLE())
	{
		Download_cURL(g_sUPDATE_URL, _sDataPath);
	}
	else if (SOCKET_AVAILABLE())
	{
		Download_Socket(g_sUPDATE_URL, _sDataPath);
	}
}

public Action:Timer_RetryQueue(Handle:timer)
{
	ProcessDownloadQueue();
	
	return Plugin_Stop;
}

DownloadEnded(bool:successful, const String:error[]="")
{
	if (successful)
	{
		LogMessage("File downloaded");
		
		new Handle:hKeyValues = CreateKeyValues("Updater");
		if(FileToKeyValues(hKeyValues, _sDataPath))
		{
			if (KvGotoFirstSubKey(hKeyValues))
			{
				DeleteFile(g_sLogFile);
				
				LogToFileEx(g_sLogFile, "################################################################\n");

				LogToFileEx(g_sLogFile, "Проверка обновлений VIP\n \n");
				/*
				do
				{
					KvGetSectionName(hKeyValues, sPlugin, sizeof(sPlugin));
					KvGetString(hKeyValues, "Version", sVersion, sizeof(sVersion));
					LogMessage("sPlugin: '%s'", sPlugin);
					LogMessage("sVersion: '%s'", sVersion);
					
				} while (KvGotoNextKey(hKeyValues));
				*/
				KvRewind(hKeyValues);

				decl String:sPlugin[128], String:sVersion[64], String:sPluginName[64], String:sPluginVersion[64], String:sPluginUrl[256], String:sType[32], String:sInfo[512], Handle:hPluginIterator, Handle:hPlugin, index;  
				hPluginIterator = GetPluginIterator();  
				while (MorePlugins(hPluginIterator))  
				{
					hPlugin = ReadPlugin(hPluginIterator);
					GetPluginFilename(hPlugin, sPlugin, sizeof(sPlugin));
					GetPluginInfo(hPlugin, PlInfo_Name, sPluginName, sizeof(sPluginName));
					GetPluginInfo(hPlugin, PlInfo_Version, sPluginVersion, sizeof(sPluginVersion));
					LogMessage("FileName: %s", sPlugin);
					LogMessage("Name: %s", sPluginName);
					LogMessage("Version: %s", sPluginVersion);
					
					/*
					012345678 9 10 11 12 13 
					vip\VIP_m _ 1  .  1  .  smx
					10
					17
					
					*/
					if(StrContains(sPlugin, "vip", false) != -1)
					{
						index = FindCharInString(sPlugin, '_', true);
						if(index != -1 && FindCharInString(sPlugin, '_') != index)
						{
							sPlugin[index] = 0;
						}
						else
						{
							sPlugin[strlen(sPlugin)-4] = 0;
						}

						index = FindCharInString(sPlugin, '/')+1;
						if(index == 0)
						{
							index = FindCharInString(sPlugin, '\\')+1;
						}

						strcopy(sPlugin, sizeof(sPlugin), sPlugin[index]);
						LogMessage("PluginName: %s", sPlugin);
						
						KvRewind(hKeyValues);
						if(KvJumpToKey(hKeyValues, sPlugin))
						{
							LogMessage("KvJumpToKey(%s)", sPlugin);
							
							KvGetString(hKeyValues, "Version", sVersion, sizeof(sVersion));
							LogMessage("PluginVersion = '%s', Version: '%s'", sPluginVersion, sVersion);
							
							index = strlen(sVersion)-1;
							if(sVersion[index] == '0' && sVersion[index-1] != '.')
							{
								while(sVersion[index] == '0')
								{
									if(sVersion[index-1] == '.')
									{
										++index;
										break;
									}

									if(sVersion[index-1] != '0')
									{
										break;
									}

									--index;
								}

								LogMessage("index = %i", index);
								sVersion[index] = 0;
							}

							if(strcmp(sPluginVersion, sVersion) != 0)
							{
								KvGetString(hKeyValues, "url", sPluginUrl, sizeof(sPluginUrl));
								LogToFileEx(g_sLogFile, "Плагин %s устарел! (Ваша версия: %s, Последняя версия: %s)\n", sPluginName, sPluginVersion, sVersion);
								
								if(KvJumpToKey(hKeyValues, "Information"))
								{
									LogMessage("KvJumpToKey(%s)", "Information");
									if(KvJumpToKey(hKeyValues, sVersion))
									{
										LogMessage("KvJumpToKey(%s)", sVersion);
										if(KvGotoFirstSubKey(hKeyValues, false))
										{
											LogMessage("KvGotoFirstSubKey");
											do
											{
												KvGetSectionName(hKeyValues, sType, sizeof(sType));
												KvGetString(hKeyValues, NULL_STRING, sInfo, sizeof(sInfo));
												LogToFileEx(g_sLogFile, "\t%s %s", sType, sInfo);
												
											} while (KvGotoNextKey(hKeyValues, false));
										}
									}
								}

								if(sPluginUrl[0])
								{
									LogToFileEx(g_sLogFile, "Подробнее: %s\n", sPluginUrl);
								}
								LogToFileEx(g_sLogFile, "---------------------------------------------------\n");
							}
						}
					}
				}

				CloseHandle(hPluginIterator);
				
				LogToFileEx(g_sLogFile, "################################################################\n");
			}
		}

		CloseHandle(hKeyValues);
	}
}

PrefixURL(String:buffer[], maxlength, const String:url[])
{
	if (strncmp(url, "http://", 7) != 0 && strncmp(url, "https://", 8) != 0)
	{
		Format(buffer, maxlength, "http://%s", url);
	}
	else
	{
		strcopy(buffer, maxlength, url);
	}
}

ParseURL(const String:url[], String:host[], maxHost, String:location[], maxLoc, String:filename[], maxName)
{
	// Strip url prefix.
	new idx = StrContains(url, "://");
	idx = (idx != -1) ? idx + 3 : 0;
	
	decl String:dirs[16][64];
	new total = ExplodeString(url[idx], "/", dirs, sizeof(dirs), sizeof(dirs[]));
	
	// host
	Format(host, maxHost, "%s", dirs[0]);
	
	// location
	location[0] = '\0';
	for (new i = 1; i < total - 1; i++)
	{
		Format(location, maxLoc, "%s/%s", location, dirs[i]);
	}
	
	// filename
	Format(filename, maxName, "%s", dirs[total-1]);
}
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
	// cURL
	MarkNativeAsOptional("curl_OpenFile");
	MarkNativeAsOptional("curl_slist");
	MarkNativeAsOptional("curl_slist_append");
	MarkNativeAsOptional("curl_easy_init");
	MarkNativeAsOptional("curl_easy_setopt_int_array");
	MarkNativeAsOptional("curl_easy_setopt_handle");
	MarkNativeAsOptional("curl_easy_setopt_string");
	MarkNativeAsOptional("curl_easy_perform_thread");
	MarkNativeAsOptional("curl_easy_strerror");
	
	// Socket
	MarkNativeAsOptional("SocketCreate");
	MarkNativeAsOptional("SocketSetArg");
	MarkNativeAsOptional("SocketSetOption");
	MarkNativeAsOptional("SocketConnect");
	MarkNativeAsOptional("SocketSend");
	
	// SteamTools
	MarkNativeAsOptional("Steam_CreateHTTPRequest");
	MarkNativeAsOptional("Steam_SetHTTPRequestHeaderValue");
	MarkNativeAsOptional("Steam_SendHTTPRequest");
	MarkNativeAsOptional("Steam_WriteHTTPResponseBody");
	MarkNativeAsOptional("Steam_ReleaseHTTPRequest");

	return APLRes_Success;
}