/* ***********************************************************************
//
//   Copyright (C) 2025 -- The 4D-STAR Collaboration
//   File Author: Emily Boudreaux
//   Last Modified: March 20, 2025
//
//   4DSSE is free software; you can use it and/or modify
//   it under the terms and restrictions the GNU General Library Public
//   License version 3 (GPLv3) as published by the Free Software Foundation.
//
//   4DSSE is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU Library General Public License for more details.
//
//   You should have received a copy of the GNU Library General Public License
//   along with this software; if not, write to the Free Software
//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// *********************************************************************** */
#include <iostream>
#include <vector>
#include <string>
#include <filesystem>

#include "quill/LogMacros.h"

#include "resourceManager.h"
#include "resourceManagerTypes.h"
#include "debug.h"

#include "config.h"

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

namespace serif::resource {
    ResourceManager::ResourceManager() {
        const std::string defaultDataDir = TOSTRING(DATA_DIR);
        m_dataDir = m_config.get<std::string>("Data:Dir", defaultDataDir);
        // -- Get the index file path using filesystem to make it a system safe path
        const std::string indexFilePath = m_dataDir + "/index.yaml";
        // TODO Add checks to make sure data dir exists and index.yaml exists
        const std::filesystem::path indexFile(indexFilePath);

        m_resourceConfig.loadConfig(indexFile.string());
        for (const auto& key : m_resourceConfig.keys() ) {
            load(key);
        }
    }


    std::vector<std::string> ResourceManager::getAvailableResources() const {
        const std::vector<std::string> resources = m_resourceConfig.keys();
        return resources;
    }

    const serif::resource::types::Resource& ResourceManager::getResource(const std::string &name) const {
        if (const auto it = m_resources.find(name); it != m_resources.end()) {
            return it->second;
        }
        throw std::runtime_error("Resource " + name + " not found");
    }


    bool ResourceManager::loadResource(std::string& name) {
        return load(name);
    }

    bool ResourceManager::load(const std::string& name) {
        // TODO : make this path system more system agnostic
        const std::string resourcePath = m_dataDir + "/" + m_resourceConfig.get<std::string>(name);
        const std::filesystem::path resourceFile(resourcePath);
        if (!std::filesystem::exists(resourceFile)) {
            LOG_ERROR(m_logger, "Resource file not found: {}", resourceFile.string());
            return false;
        }
        LOG_INFO(m_logger, "Loading resource: {}", resourceFile.string());
        if (m_resources.contains(name)) {
            LOG_INFO(m_logger, "Resource already loaded: {}", name);
            return true;
        }
        serif::resource::types::Resource resource = serif::resource::types::createResource(name, resourcePath);
        m_resources[name] = std::move(resource);
        // -- Check if the resource is already in the map
        return true;
    }
}

