#include "hash.hpp"
#include "dshash.hpp"

#include <filesystem>
#include <iostream>
#include <chrono>

namespace simple_object_storage {

std::string hash_file(const std::string &path) {
    // Check if file exists
    if (!std::filesystem::exists(path)) {
        std::cerr << "Failed to open file: " << path << std::endl;
        return "";
    }
    
    try {
        // Create a DSHash object from file path
        std::filesystem::path filepath(path);
        DSHash hasher(filepath);
        return hasher.toString();
    } catch (const std::exception& e) {
        std::cerr << "Failed to hash file: " << e.what() << std::endl;
        return "";
    }
}

std::string hash_directory_recursive(const std::string &path) {
    try {
        // DSHash handles directories internally by hashing all files in sorted order
        std::filesystem::path dirpath(path);
        DSHash hasher(dirpath);
        return hasher.toString();
    } catch (const std::exception& e) {
        std::cerr << "Failed to hash directory: " << e.what() << std::endl;
        return "";
    }
}

void hash_demo(const std::string & path) {
    std::cout << "Hashing directory: " << path << std::endl;
    auto start = std::chrono::high_resolution_clock::now();
    std::string hash = hash_directory_recursive(path);
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << "SHA-256 Hash: " << hash << " (took " << duration.count() << "ms)" << std::endl;
}

int hash_demo_raw(const std::string & path) {
    if (!std::filesystem::exists(path)) {
        std::cout << "0" << std::endl; 
        return 1;
    }
    std::string hash = hash_directory_recursive(path);
    std::cout << hash << std::endl;
    return 0;
}

} // namespace simple_object_storage