import { createPrivateKey, createPublicKey, generateKeyPairSync, sign, } from "node:crypto";
const DEVICE_KEY_PROVIDER = "patchtrail_device";
const DEVICE_KEY_KIND = "device_pairing_private_key";
export class DeviceKeyManager {
    #secureStore;
    constructor(secureStore) {
        this.#secureStore = secureStore;
    }
    /** Loads the device key, generating and persisting one on first use. */
    async ensureDeviceKey(deviceId) {
        const existing = await this.loadDeviceKey(deviceId);
        if (existing) {
            return existing;
        }
        const { publicKey, privateKey } = generateKeyPairSync("ec", {
            namedCurve: "P-256",
        });
        const pkcs8Pem = privateKey
            .export({ type: "pkcs8", format: "pem" })
            .toString();
        await this.#secureStore.set(this.#ref(deviceId), pkcs8Pem);
        return { privateKey, publicKeySpkiBase64: exportSpkiBase64(publicKey) };
    }
    /** Returns the stored device key, or null when none has been generated. */
    async loadDeviceKey(deviceId) {
        const stored = await this.#secureStore.get(this.#ref(deviceId));
        if (!stored) {
            return null;
        }
        const privateKey = createPrivateKey(stored);
        const publicKey = createPublicKey(privateKey);
        return { privateKey, publicKeySpkiBase64: exportSpkiBase64(publicKey) };
    }
    /**
     * Signs a value with the device private key (P-256 ECDSA, IEEE P1363),
     * returning a base64url signature, or null when the device has no key. Used
     * to prove device identity on outbound command-channel requests (Decision 2).
     */
    async signValue(deviceId, value) {
        const stored = await this.#secureStore.get(this.#ref(deviceId));
        if (!stored) {
            return null;
        }
        const privateKey = createPrivateKey(stored);
        const signature = sign("sha256", Buffer.from(value, "utf8"), {
            key: privateKey,
            dsaEncoding: "ieee-p1363",
        });
        return signature.toString("base64url");
    }
    #ref(deviceId) {
        return {
            provider: DEVICE_KEY_PROVIDER,
            kind: DEVICE_KEY_KIND,
            accountId: deviceId,
        };
    }
}
function exportSpkiBase64(publicKey) {
    return publicKey.export({ type: "spki", format: "der" }).toString("base64");
}
