import { CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE } from '@aztec/constants';
import { FieldReader } from '@aztec/foundation/serialize';
import { bufferFromFields } from '@aztec/stdlib/abi';
import { computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
import { ProtocolContractAddress } from '../protocol_contract_data.js';
/** Event emitted from the ContractClassRegistry. */ export class ContractClassPublishedEvent {
    contractClassId;
    version;
    artifactHash;
    privateFunctionsRoot;
    packedPublicBytecode;
    constructor(contractClassId, version, artifactHash, privateFunctionsRoot, packedPublicBytecode){
        this.contractClassId = contractClassId;
        this.version = version;
        this.artifactHash = artifactHash;
        this.privateFunctionsRoot = privateFunctionsRoot;
        this.packedPublicBytecode = packedPublicBytecode;
    }
    static isContractClassPublishedEvent(log) {
        return log.contractAddress.equals(ProtocolContractAddress.ContractClassRegistry) && log.fields.fields[0].toBigInt() === CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE;
    }
    static fromLog(log) {
        // See how the log is serialized in `noir-projects/noir-contracts/contracts/protocol/contract_class_registry_contract/src/events/class_published.nr`.
        const fieldsWithoutTag = log.fields.fields.slice(1);
        const reader = new FieldReader(fieldsWithoutTag);
        const contractClassId = reader.readField();
        const version = reader.readField().toNumber();
        const artifactHash = reader.readField();
        const privateFunctionsRoot = reader.readField();
        const packedPublicBytecode = bufferFromFields(reader.readFieldArray(fieldsWithoutTag.length - reader.cursor));
        return new ContractClassPublishedEvent(contractClassId, version, artifactHash, privateFunctionsRoot, packedPublicBytecode);
    }
    /** Converts the event to a contract class, without computing or validating the bytecode commitment. */ toContractClassPublic() {
        return {
            id: this.contractClassId,
            artifactHash: this.artifactHash,
            packedBytecode: this.packedPublicBytecode,
            privateFunctionsRoot: this.privateFunctionsRoot,
            version: this.version,
            privateFunctions: [],
            utilityFunctions: []
        };
    }
    /** Converts the event to a contract class with its bytecode commitment (expensive). */ async toContractClassPublicWithBytecodeCommitment() {
        const publicBytecodeCommitment = await computePublicBytecodeCommitment(this.packedPublicBytecode);
        return {
            ...this.toContractClassPublic(),
            publicBytecodeCommitment
        };
    }
    static extractContractClassEvents(logs) {
        return logs.filter((log)=>ContractClassPublishedEvent.isContractClassPublishedEvent(log)).map((log)=>ContractClassPublishedEvent.fromLog(log));
    }
}
