<?php

declare(strict_types=1);

require_once __DIR__ . '/MarketplaceTrustedKeys.php';

final class MyronMarketplaceKeyResolver
{
    /**
     * @param array<string, string> $keys
     * @param array<string, string> $ed25519PublicKeys
     */
    public function __construct(
        private readonly array $keys = [],
        private readonly array $ed25519PublicKeys = [],
    ) {
    }

    public static function fromEnvironment(): self
    {
        $keys = [];
        $rawJson = trim((string) getenv('MYRON_MARKETPLACE_KEYS_JSON'));
        if ($rawJson !== '') {
            $decoded = json_decode($rawJson, true);
            if (is_array($decoded)) {
                foreach ($decoded as $keyId => $secret) {
                    $keyId = trim((string) $keyId);
                    $secret = (string) $secret;
                    if ($keyId !== '' && $secret !== '') {
                        $keys[$keyId] = $secret;
                    }
                }
            }
        }

        $keyId = trim((string) getenv('MYRON_MARKETPLACE_KEY_ID'));
        $secret = (string) getenv('MYRON_MARKETPLACE_HMAC_KEY');
        if ($keyId !== '' && $secret !== '') {
            $keys[$keyId] = $secret;
        }

        $publicKeys = [];
        $rawPublicJson = trim((string) getenv('MYRON_MARKETPLACE_ED25519_KEYS_JSON'));
        if ($rawPublicJson !== '') {
            $decoded = json_decode($rawPublicJson, true);
            if (is_array($decoded)) {
                foreach ($decoded as $publicKeyId => $publicKey) {
                    $publicKeyId = trim((string) $publicKeyId);
                    $publicKey = trim((string) $publicKey);
                    if ($publicKeyId !== '' && $publicKey !== '') {
                        $publicKeys[$publicKeyId] = $publicKey;
                    }
                }
            }
        }

        $publicKeyId = trim((string) getenv('MYRON_MARKETPLACE_ED25519_KEY_ID'));
        $publicKey = trim((string) getenv('MYRON_MARKETPLACE_ED25519_PUBLIC_KEY'));
        if ($publicKeyId !== '' && $publicKey !== '') {
            $publicKeys[$publicKeyId] = $publicKey;
        }

        return new self($keys, $publicKeys);
    }

    public function resolve(string $keyId): string
    {
        return $this->resolveHmacSecret($keyId);
    }

    public function resolveHmacSecret(string $keyId): string
    {
        $keyId = trim($keyId);
        if ($keyId === '' || !isset($this->keys[$keyId]) || $this->keys[$keyId] === '') {
            throw new RuntimeException('marketplace_hmac_key_unavailable: ' . $keyId);
        }

        return $this->keys[$keyId];
    }

    public function resolveEd25519PublicKey(string $keyId): string
    {
        $keyId = trim($keyId);
        $keys = array_merge(MyronMarketplaceTrustedKeys::firstPartyEd25519PublicKeys(), $this->ed25519PublicKeys);
        if ($keyId === '' || !isset($keys[$keyId]) || trim((string) $keys[$keyId]) === '') {
            throw new RuntimeException('marketplace_trust_root_missing: ' . $keyId);
        }

        return trim((string) $keys[$keyId]);
    }
}
