#include "FileUtils.h"

#include "MemoryUtils.h"

auto Utils::File::getLocalFoldor() -> std::string {
    return (getenv("AppData") + (std::string)"\\..\\Local\\Packages\\Microsoft.MinecraftUWP_8wekyb3d8bbwe\\LocalState");

    std::wstring wstr = winrt::Windows::Storage::ApplicationData::Current().LocalFolder().Path().c_str();
	std::string str(wstr.begin(), wstr.end());
	return str;
}

auto Utils::File::getRoamingState() -> std::string {
    return (getenv("AppData") + (std::string)"\\..\\Local\\Packages\\Microsoft.MinecraftUWP_8wekyb3d8bbwe\\RoamingState");
    /*
    std::wstring wstr = winrt::Windows::Storage::ApplicationData::Current().RoamingFolder().Path().c_str();
    std::string str(wstr.begin(), wstr.end());
    return str;*/
}

auto Utils::File::getTempState() -> std::string {
    return (getenv("AppData") + (std::string)"\\..\\Local\\Packages\\Microsoft.MinecraftUWP_8wekyb3d8bbwe\\TempState");

    std::wstring wstr = winrt::Windows::Storage::ApplicationData::Current().RoamingFolder().Path().c_str();
    std::string str(wstr.begin(), wstr.end());
    return str;
}

auto Utils::File::downloadFile(std::string path, std::string url) -> void {
    HINTERNET webH = InternetOpenA(_("Mozilla/5.0"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL);
    HINTERNET urlFile;
    if (webH)
        urlFile = InternetOpenUrlA(webH, url.c_str(), NULL, NULL, NULL, NULL);
    else
        return;

    if (urlFile)
    {
        std::ofstream outputFile(path, std::ios::binary);
        if (outputFile.is_open())
        {
            char buffer[2000];
            DWORD bytesRead;
            do
            {
                InternetReadFile(urlFile, buffer, 2000, &bytesRead);
                outputFile.write(buffer, bytesRead);
                memset(buffer, 0, 2000);
            } while
                (bytesRead);

            outputFile.close();
            InternetCloseHandle(webH);
            InternetCloseHandle(urlFile);

            return;
        }
        else
        {
            InternetCloseHandle(webH);
            InternetCloseHandle(urlFile);
            return;
        }
    }
    else
    {
        InternetCloseHandle(webH);
        return;
    }
}

auto Utils::File::getOption(std::string option) -> std::string {
    std::ifstream file(getLocalFoldor() + _("\\games\\com.mojang\\minecraftpe\\options.txt"));
    if (!file.is_open()) return _("");


    std::string line;
    std::string pattern_str = std::string(std::regex_replace(option, std::regex(R"([\.\+\*\?\|\^\$\(\)\[\]\{\}\\])"), R"(\$&)") + R"(:\s*(\d+))");

    std::regex pattern(pattern_str);

    while (std::getline(file, line)) {
        std::smatch match;
        if (std::regex_search(line, match, pattern)) {
            return match[1].str();
        }
    }

    return _("");
}

auto Utils::File::getVersion() -> std::string {
    static std::string version = _("");
    if (version == _("")) {
        TCHAR szPath[_MAX_PATH] = { 0 };
        if (GetModuleFileName((HMODULE)Utils::Memory::getHandle(), szPath, _MAX_PATH - 1) == 0) {
            return version;
        }

        std::wstring mcPath = szPath;

        DWORD handle = 0;
        DWORD versioninfosize = GetFileVersionInfoSize(mcPath.c_str(), &handle);
        if (versioninfosize == 0) {
            return version;
        }

        std::unique_ptr<char[]> versioninfobuffer(new(std::nothrow) char[versioninfosize]);
        if (!versioninfobuffer) {
            return version;
        }

        if (!GetFileVersionInfo(mcPath.c_str(), 0, versioninfosize, versioninfobuffer.get())) {
            return version;
        }

        VS_FIXEDFILEINFO* fileinfo = nullptr;
        UINT fileinfosize = 0;
        if (!VerQueryValue(versioninfobuffer.get(), L"\\", reinterpret_cast<void**>(&fileinfo), &fileinfosize)) {
            return version;
        }

        version = std::format("{:d}.{:d}.{:d}",
            HIWORD(fileinfo->dwFileVersionMS), LOWORD(fileinfo->dwFileVersionMS),
            HIWORD(fileinfo->dwFileVersionLS), LOWORD(fileinfo->dwFileVersionLS)
        );
    }

    return version;
}
