<?php
declare(strict_types=1);

namespace SafeTun\Backend\Crypto;

final class KeyLoader
{
    public static function secret(string $path): string
    {
        return self::read($path, SODIUM_CRYPTO_SIGN_SECRETKEYBYTES);
    }

    public static function public(string $path): string
    {
        return self::read($path, SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES);
    }

    private static function read(string $path, int $expectedLength): string
    {
        if (!extension_loaded('sodium')) {
            throw new \RuntimeException('The Sodium extension is required.');
        }
        if (!is_file($path) || !is_readable($path)) {
            throw new \RuntimeException("Signing key is not readable: {$path}");
        }
        $content = file_get_contents($path);
        if (!is_string($content)) {
            throw new \RuntimeException("Unable to read signing key: {$path}");
        }
        if (strlen($content) === $expectedLength) {
            return $content;
        }

        $trimmed = trim($content);
        try {
            if (str_starts_with($trimmed, 'base64:')) {
                return Base64Url::decode(substr($trimmed, 7), $expectedLength);
            }
            if (str_starts_with($trimmed, 'hex:')) {
                $trimmed = substr($trimmed, 4);
            }
            if (preg_match('/^[0-9a-fA-F]+$/D', $trimmed) && strlen($trimmed) === $expectedLength * 2) {
                $decoded = hex2bin($trimmed);
                if (is_string($decoded)) {
                    return $decoded;
                }
            }
            return Base64Url::decode($trimmed, $expectedLength);
        } catch (\InvalidArgumentException $exception) {
            throw new \RuntimeException("Signing key has an invalid encoding or length: {$path}", 0, $exception);
        }
    }
}
