"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.claimCertificates = exports.transferCertificates = exports.getIdsFromBatchIssuanceTx = exports.issueCertificates = void 0;
const ethers_1 = require("ethers");
const Certificate_1 = require("./Certificate");
const CertificateUtils_1 = require("./CertificateUtils");
function issueCertificates(certificateInfo, blockchainProperties) {
    return __awaiter(this, void 0, void 0, function* () {
        const { issuer, activeUser } = blockchainProperties;
        const issuerWithSigner = issuer.connect(activeUser);
        const data = certificateInfo.map((info) => (0, CertificateUtils_1.encodeData)({
            generationStartTime: info.generationStartTime,
            generationEndTime: info.generationEndTime,
            deviceId: info.deviceId,
            metadata: info.metadata
        }));
        return yield issuerWithSigner.issueBatch(certificateInfo.map((info) => info.to), certificateInfo.map((info) => info.amount), data);
    });
}
exports.issueCertificates = issueCertificates;
function getIdsFromBatchIssuanceTx(txHash, { web3, issuer, registry }) {
    return __awaiter(this, void 0, void 0, function* () {
        const txReceipt = yield web3.getTransactionReceipt(txHash);
        if (!txReceipt) {
            throw new Error(`Tx ${txHash} not mined yet`);
        }
        const { logs } = txReceipt;
        let issuanceEvent;
        for (const event of logs) {
            try {
                issuanceEvent = issuer.interface.parseLog(event);
            }
            catch (e) {
                issuanceEvent = registry.interface.parseLog(event);
            }
            if (issuanceEvent.name === 'IssuanceBatch') {
                break;
            }
        }
        return issuanceEvent.args[2].map((id) => id.toNumber());
    });
}
exports.getIdsFromBatchIssuanceTx = getIdsFromBatchIssuanceTx;
function transferCertificates(certificateBatch, blockchainProperties) {
    return __awaiter(this, void 0, void 0, function* () {
        const certificatesPromises = certificateBatch.map((cert) => new Certificate_1.Certificate(cert.id, blockchainProperties).sync());
        const { registry, activeUser } = blockchainProperties;
        const registryWithSigner = registry.connect(activeUser);
        const activeUserAddress = yield activeUser.getAddress();
        const certificates = yield Promise.all(certificatesPromises);
        return yield registryWithSigner.safeBatchTransferFromMultiple(certificateBatch.map((cert) => { var _a; return (_a = cert.from) !== null && _a !== void 0 ? _a : activeUserAddress; }), certificateBatch.map((cert) => cert.to), certificateBatch.map((cert) => cert.id), certificateBatch.map((cert) => {
            var _a, _b, _c;
            return (_a = cert.amount) !== null && _a !== void 0 ? _a : ethers_1.BigNumber.from((_c = certificates.find((certificate) => certificate.id === cert.id).owners[(_b = cert.from) !== null && _b !== void 0 ? _b : activeUserAddress]) !== null && _c !== void 0 ? _c : 0);
        }), certificateBatch.map(() => ethers_1.utils.randomBytes(32)) // TO-DO: replace with proper data
        );
    });
}
exports.transferCertificates = transferCertificates;
function claimCertificates(certificateBatch, blockchainProperties) {
    return __awaiter(this, void 0, void 0, function* () {
        const certificatesPromises = certificateBatch.map((cert) => new Certificate_1.Certificate(cert.id, blockchainProperties).sync());
        const certificates = yield Promise.all(certificatesPromises);
        const { activeUser, registry } = blockchainProperties;
        const activeUserAddress = yield activeUser.getAddress();
        const registryWithSigner = registry.connect(activeUser);
        return yield registryWithSigner.safeBatchTransferAndClaimFromMultiple(certificateBatch.map((cert) => { var _a; return (_a = cert.from) !== null && _a !== void 0 ? _a : activeUserAddress; }), certificateBatch.map((cert) => { var _a, _b; return (_b = (_a = cert.to) !== null && _a !== void 0 ? _a : cert.from) !== null && _b !== void 0 ? _b : activeUserAddress; }), certificateBatch.map((cert) => cert.id), certificateBatch.map((cert) => {
            var _a, _b, _c;
            return (_a = cert.amount) !== null && _a !== void 0 ? _a : ethers_1.BigNumber.from((_c = certificates.find((certificate) => certificate.id === cert.id).owners[(_b = cert.from) !== null && _b !== void 0 ? _b : activeUserAddress]) !== null && _c !== void 0 ? _c : 0);
        }), certificateBatch.map(() => ethers_1.utils.randomBytes(32)), // TO-DO: replace with proper data
        certificateBatch.map((cert) => (0, CertificateUtils_1.encodeClaimData)(cert.claimData)));
    });
}
exports.claimCertificates = claimCertificates;
//# sourceMappingURL=CertificateBatchOperations.js.map