#include "config.hpp"
#include "logger.hpp"
#include <fstream>
#include <sstream>
#include <iostream>
#include <nlohmann/json.hpp>

#include "assert.hpp"

namespace simple_object_storage {

bool load_config(const std::string& config_path, ServerConfig& config) {
    try {
        if (config_path.empty()) {
            LOG_ERROR("Config path is empty");
            return false;
        }
        if (!std::filesystem::exists(config_path)) {
            LOG_ERROR("Config file does not exist: {}", config_path);
            return false;
        }

        std::ifstream file(config_path);
        if (!file.is_open()) {
            LOG_ERROR("Failed to open config file: {}", config_path);
            return false;
        }

        nlohmann::json j;
        file >> j;

        config = ServerConfig(); // set defaults.

        // Parse write tokens
        if (j.contains("write_tokens")) {
            config.write_tokens = j["write_tokens"].get<std::vector<std::string>>();
        }

        // Parse object store path
        if (j.contains("object_store_path")) {
            config.object_store_path = j["object_store_path"].get<std::string>();
        }

        // Parse host (optional)
        if (j.contains("host")) {
            config.host = j["host"].get<std::string>();
        }

        // Parse port (optional)
        if (j.contains("port")) {
            config.port = j["port"].get<uint16_t>();
        }

        // Parse CORS configuration
        if (j.contains("cors")) {
            const auto& cors = j["cors"];
            if (cors.contains("allowed_origins")) {
                config.allowed_origins = cors["allowed_origins"].get<std::vector<std::string>>();
            }
            if (cors.contains("allowed_methods")) {
                config.allowed_methods = cors["allowed_methods"].get<std::vector<std::string>>();
            }
            if (cors.contains("allowed_headers")) {
                config.allowed_headers = cors["allowed_headers"].get<std::vector<std::string>>();
            }
            if (cors.contains("allow_credentials")) {
                config.allow_credentials = cors["allow_credentials"].get<bool>();
            }
        }

        // Parse rate limiting configuration
        if (j.contains("rate_limiting")) {
            const auto& rate_limit = j["rate_limiting"];
            if (rate_limit.contains("auth_rate_limit")) {
                config.auth_rate_limit = rate_limit["auth_rate_limit"].get<int>();
            }
            if (rate_limit.contains("auth_window_seconds")) {
                config.auth_window_seconds = rate_limit["auth_window_seconds"].get<int>();
            }
        }

        // Parse logging configuration
        if (j.contains("logging")) {
            const auto& logging = j["logging"];
            if (logging.contains("log_file_path")) {
                config.log_file_path = logging["log_file_path"].get<std::string>();
            }
            if (logging.contains("log_level")) {
                config.log_level = logging["log_level"].get<std::string>();
            }
        }

        // Line number accuracy improved

        return true;
    } catch (const std::exception& e) {
        LOG_ERROR("Error parsing config file: {}", e.what());
        return false;
    }
}

} // namespace simple_object_storage 