#include "engine_crypto.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sodium.h>

void print_usage() {
    std::cerr << "Usage: verify-hmac --ts <timestamp> --nonce <nonce> --method <METHOD> --path <path> --payload <payload_file> --sig <expected_sig> --key <key_file>\n";
    std::cerr << "  CRY-02 canonical: HMAC-SHA256( ts.nonce.METHOD.path.body )\n";
}

int main(int argc, char* argv[]) {
    if (sodium_init() < 0) {
        std::cerr << "Failed to initialize libsodium\n";
        return 1;
    }

    std::string ts, nonce, method, path, payload_path, sig, key_path;

    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "--ts" && i + 1 < argc) ts = argv[++i];
        else if (arg == "--nonce" && i + 1 < argc) nonce = argv[++i];
        else if (arg == "--method" && i + 1 < argc) method = argv[++i];
        else if (arg == "--path" && i + 1 < argc) path = argv[++i];
        else if (arg == "--payload" && i + 1 < argc) payload_path = argv[++i];
        else if (arg == "--sig" && i + 1 < argc) sig = argv[++i];
        else if (arg == "--key" && i + 1 < argc) key_path = argv[++i];
    }

    if (ts.empty() || nonce.empty() || method.empty() || path.empty() || payload_path.empty() || sig.empty() || key_path.empty()) {
        print_usage();
        return 1;
    }

    std::ifstream kf(key_path);
    if (!kf.is_open()) {
        std::cerr << "Failed to open key file\n";
        return 1;
    }
    std::string key((std::istreambuf_iterator<char>(kf)), std::istreambuf_iterator<char>());
    while (!key.empty() && (key.back() == '\n' || key.back() == '\r')) key.pop_back();

    std::ifstream pf(payload_path);
    if (!pf.is_open()) {
        std::cerr << "Failed to open payload file\n";
        return 1;
    }
    std::string payload((std::istreambuf_iterator<char>(pf)), std::istreambuf_iterator<char>());

    // CRY-02 canonical: ts.nonce.METHOD.path.body
    std::string data = ts + "." + nonce + "." + method + "." + path + "." + payload;
    
    node669427::CryptoEngine crypto;
    crypto.loadKeyFromBuffer(key);
    std::string expected = crypto.hmacSha256(data);

    if (expected.length() != sig.length()) {
        std::cout << "FAIL (length mismatch)\n";
        return 1;
    }

    if (sodium_memcmp(expected.data(), sig.data(), expected.length()) == 0) {
        std::cout << "PASS\n";
        return 0;
    } else {
        std::cout << "FAIL\n";
        return 1;
    }
}
