"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSigner = exports.SigningGroupNotInitializedError = exports.SigningGroup = void 0;
const cloud_library_1 = require("@dfns/cloud-library");
const Foundations_1 = require("@dfns/datamodel/dist/Foundations");
const private_api_client_1 = require("@dfns/private-api-client");
const constants_1 = require("./constants");
class SigningGroup {
    // eslint-disable-next-line @typescript-eslint/no-empty-function
    constructor() {
        this.headers = {};
    }
    static builder() {
        return new SigningGroup();
    }
    setOrgId(orgId) {
        this.orgId = orgId;
        return this;
    }
    setPublicKeyId(publicKeyId) {
        this.publicKeyId = publicKeyId;
        return this;
    }
    setPrivateApiUrl(privateApiUrl) {
        this.privateApiUrl = privateApiUrl;
        return this;
    }
    buildClient() {
        this.privateApiUrl = this.resolvePrivateApiUrl();
        this.api = new private_api_client_1.PrivateApiClient(constants_1.SERVICE_NAME, this.privateApiUrl);
        return this;
    }
    async build() {
        this.checkRequiredParameters();
        this.buildClient();
        await this.init();
        return this;
    }
    checkRequiredParameters() {
        if (!this.publicKeyId) {
            throw new Foundations_1.BadRequestError('publicKeyId not defined', constants_1.SERVICE_NAME);
        }
        if (!this.orgId) {
            throw new Foundations_1.BadRequestError('orgId not defined', constants_1.SERVICE_NAME);
        }
    }
    resolvePrivateApiUrl() {
        const PRIVATE_API_URL = process.env[cloud_library_1.EnvVar.PRIVATE_API_URL];
        const DEFAULT_PRIVATE_API_URL = 'https://api.private.dfns.wtf';
        if (!PRIVATE_API_URL && !this.privateApiUrl) {
            cloud_library_1.logger.warn(`SigningGroup: PRIVATE_API_URL is not initialized, using default: ${DEFAULT_PRIVATE_API_URL}`);
        }
        return this.privateApiUrl || PRIVATE_API_URL || DEFAULT_PRIVATE_API_URL;
    }
    async init() {
        this.publicKey = await this.getPublicKeyAsync();
    }
    getPublicKey() {
        this.checkPublicKeyInitialized();
        return this.publicKey;
    }
    checkInitializedAndRequiredParameters() {
        this.checkClientInitialized();
        this.checkRequiredParameters();
    }
    checkClientInitialized() {
        if (!this.api) {
            throw new SigningGroupNotInitializedError('api client not provided');
        }
    }
    checkPublicKeyInitialized() {
        if (!this.publicKey) {
            throw new SigningGroupNotInitializedError('publicKey not initialized');
        }
    }
    async getPublicKeyAsync() {
        this.checkInitializedAndRequiredParameters();
        const { publicKey } = await this.api.signersCoordinator.getPublicKey({
            orgId: this.orgId,
            publicKeyId: this.publicKeyId,
        });
        return Buffer.from(publicKey, 'hex');
    }
    async sign(hash) {
        this.checkInitializedAndRequiredParameters();
        const hashStr = Buffer.isBuffer(hash) ? hash.toString('hex') : hash;
        const signature = await this.api.signersCoordinator.sign({
            orgId: this.orgId,
            publicKeyId: this.publicKeyId,
            hash: hashStr,
        });
        return signature;
    }
}
exports.SigningGroup = SigningGroup;
class SigningGroupNotInitializedError extends Error {
    constructor(message) {
        super(`SigningGroup for is not initialized. ${message}`);
    }
}
exports.SigningGroupNotInitializedError = SigningGroupNotInitializedError;
function createSigner({ orgId, publicKeyId }) {
    return SigningGroup.builder().setOrgId(orgId).setPublicKeyId(publicKeyId).build();
}
exports.createSigner = createSigner;
