// D:\Dev\Mosis\MosisService\designer\src\desktop_file_interface.cpp
#include "desktop_file_interface.h"
#include <cstdio>
#include <cctype>
#include <filesystem>

namespace fs = std::filesystem;

namespace mosis {

void DesktopFileInterface::SetAssetsPath(const std::string& path) {
    m_assets_path = path;
    // Ensure trailing separator
    if (!m_assets_path.empty() && m_assets_path.back() != '/' && m_assets_path.back() != '\\') {
        m_assets_path += '/';
    }
}

std::string DesktopFileInterface::ResolvePath(const std::string& path) const {
    std::string resolved = path;

    // Handle file:// URLs
    if (resolved.rfind("file://", 0) == 0) {
        resolved = resolved.substr(7);  // Strip "file://"
    }

    // Handle URL-encoded Windows drive letters (D| -> D:)
    // RmlUi sometimes encodes the colon in Windows paths
    if (resolved.size() >= 2 && std::isalpha(resolved[0]) && resolved[1] == '|') {
        resolved[1] = ':';
    }

    // If path is absolute, use it directly
    if (fs::path(resolved).is_absolute()) {
        return resolved;
    }
    // Otherwise, prepend assets path
    return m_assets_path + resolved;
}

Rml::FileHandle DesktopFileInterface::Open(const Rml::String& path) {
    std::string resolved = ResolvePath(path);
    FILE* file = fopen(resolved.c_str(), "rb");
    return reinterpret_cast<Rml::FileHandle>(file);
}

void DesktopFileInterface::Close(Rml::FileHandle file) {
    if (file) {
        fclose(reinterpret_cast<FILE*>(file));
    }
}

size_t DesktopFileInterface::Read(void* buffer, size_t size, Rml::FileHandle file) {
    if (!file) return 0;
    return fread(buffer, 1, size, reinterpret_cast<FILE*>(file));
}

bool DesktopFileInterface::Seek(Rml::FileHandle file, long offset, int origin) {
    if (!file) return false;
    return fseek(reinterpret_cast<FILE*>(file), offset, origin) == 0;
}

size_t DesktopFileInterface::Tell(Rml::FileHandle file) {
    if (!file) return 0;
    return static_cast<size_t>(ftell(reinterpret_cast<FILE*>(file)));
}

size_t DesktopFileInterface::Length(Rml::FileHandle file) {
    if (!file) return 0;
    
    FILE* f = reinterpret_cast<FILE*>(file);
    long current = ftell(f);
    fseek(f, 0, SEEK_END);
    long length = ftell(f);
    fseek(f, current, SEEK_SET);
    
    return static_cast<size_t>(length);
}

} // namespace mosis
