"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NegotiationFieldsV2 = exports.NegotiationFieldsV1 = exports.NegotiationFieldsV0 = exports.DisjointNegotiationFields = exports.SingleNegotiationFields = exports.NegotiationFields = void 0;
const bufio_1 = require("@node-dlc/bufio");
const RoundingIntervals_1 = require("./RoundingIntervals");
/**
 * Negotiation fields for DLC contract negotiation.
 * Follows the Rust enum pattern with Single and Disjoint variants.
 */
class NegotiationFields {
    static deserialize(buf) {
        const reader = new bufio_1.BufferReader(buf);
        const discriminator = Number(reader.readBigSize());
        switch (discriminator) {
            case 0:
                return SingleNegotiationFields.deserialize(buf);
            case 1:
                return DisjointNegotiationFields.deserialize(buf);
            default:
                throw new Error(`Invalid NegotiationFields discriminator: ${discriminator}. Must be 0 (Single) or 1 (Disjoint)`);
        }
    }
    /**
     * Creates a NegotiationFields from JSON data
     * @param json JSON object representing negotiation fields
     */
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
    static fromJSON(json) {
        if (!json || typeof json !== 'object') {
            throw new Error('Invalid JSON input for NegotiationFields');
        }
        const variant = json.variant;
        switch (variant) {
            case 'Single':
                return SingleNegotiationFields.fromJSON(json);
            case 'Disjoint':
                return DisjointNegotiationFields.fromJSON(json);
            default:
                throw new Error(`Unknown negotiation fields variant: ${variant}. Must be 'Single' or 'Disjoint'`);
        }
    }
}
exports.NegotiationFields = NegotiationFields;
/**
 * Negotiation fields for contract based on a single event.
 */
class SingleNegotiationFields extends NegotiationFields {
    constructor() {
        super(...arguments);
        this.variant = 'Single';
        this.discriminator = 0;
    }
    /**
     * Creates a SingleNegotiationFields from JSON data
     * @param json JSON object representing single negotiation fields
     */
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
    static fromJSON(json) {
        const instance = new SingleNegotiationFields();
        if (json.variant !== 'Single') {
            throw new Error(`Invalid variant for SingleNegotiationFields: expected 'Single', got ${json.variant}`);
        }
        if (!json.roundingIntervals) {
            throw new Error('SingleNegotiationFields requires roundingIntervals field');
        }
        instance.roundingIntervals = RoundingIntervals_1.RoundingIntervals.fromJSON(json.roundingIntervals);
        return instance;
    }
    /**
     * Deserializes single negotiation fields
     * @param buf
     */
    static deserialize(buf) {
        const instance = new SingleNegotiationFields();
        const reader = new bufio_1.BufferReader(buf);
        reader.readBigSize(); // read discriminator (0)
        // Read remaining bytes as raw RoundingIntervals data
        const remainingBytes = reader.readBytes();
        instance.roundingIntervals = RoundingIntervals_1.RoundingIntervals.deserialize(remainingBytes);
        return instance;
    }
    /**
     * Converts single negotiation fields to JSON
     */
    toJSON() {
        return {
            variant: this.variant,
            roundingIntervals: this.roundingIntervals.toJSON(),
        };
    }
    /**
     * Serializes the single negotiation fields into a Buffer
     */
    serialize() {
        const writer = new bufio_1.BufferWriter();
        writer.writeBigSize(this.discriminator);
        writer.writeBytes(this.roundingIntervals.serialize());
        return writer.toBuffer();
    }
}
exports.SingleNegotiationFields = SingleNegotiationFields;
/**
 * Negotiation fields for contract based on multiple events.
 */
class DisjointNegotiationFields extends NegotiationFields {
    constructor() {
        super(...arguments);
        this.variant = 'Disjoint';
        this.discriminator = 1;
        this.negotiationFields = [];
    }
    /**
     * Creates a DisjointNegotiationFields from JSON data
     * @param json JSON object representing disjoint negotiation fields
     */
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
    static fromJSON(json) {
        const instance = new DisjointNegotiationFields();
        if (json.variant !== 'Disjoint') {
            throw new Error(`Invalid variant for DisjointNegotiationFields: expected 'Disjoint', got ${json.variant}`);
        }
        if (!json.negotiationFields || !Array.isArray(json.negotiationFields)) {
            throw new Error('DisjointNegotiationFields requires negotiationFields array');
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        instance.negotiationFields = json.negotiationFields.map((fieldJson) => NegotiationFields.fromJSON(fieldJson));
        return instance;
    }
    /**
     * Deserializes disjoint negotiation fields
     * @param buf
     */
    static deserialize(buf) {
        const instance = new DisjointNegotiationFields();
        const reader = new bufio_1.BufferReader(buf);
        reader.readBigSize(); // read discriminator (1)
        const numFields = Number(reader.readBigSize());
        for (let i = 0; i < numFields; i++) {
            // For simplicity, let's read the nested field by looking ahead
            // to determine its length based on its discriminator
            const startPos = reader.position;
            const discriminator = Number(reader.readBigSize());
            if (discriminator === 0) {
                // Single field: discriminator + RoundingIntervals data
                // RoundingIntervals has its own length, so we need to parse it
                const roundingIntervals = RoundingIntervals_1.RoundingIntervals.deserialize(reader.readBytes());
                // Reset and read the complete field
                reader.position = startPos;
                const fieldLength = 1 + roundingIntervals.serialize().length; // discriminator + data length
                const fieldData = reader.readBytes(fieldLength);
                instance.negotiationFields.push(NegotiationFields.deserialize(fieldData));
            }
            else if (discriminator === 1) {
                throw new Error('Nested disjoint fields not yet supported');
            }
            else {
                throw new Error(`Unknown discriminator: ${discriminator}`);
            }
        }
        return instance;
    }
    /**
     * Converts disjoint negotiation fields to JSON
     */
    toJSON() {
        return {
            variant: this.variant,
            negotiationFields: this.negotiationFields.map((field) => field.toJSON()),
        };
    }
    /**
     * Serializes the disjoint negotiation fields into a Buffer
     */
    serialize() {
        const writer = new bufio_1.BufferWriter();
        writer.writeBigSize(this.discriminator);
        writer.writeBigSize(this.negotiationFields.length);
        for (const negotiationField of this.negotiationFields) {
            writer.writeBytes(negotiationField.serialize());
        }
        return writer.toBuffer();
    }
}
exports.DisjointNegotiationFields = DisjointNegotiationFields;
// Legacy exports for backward compatibility - map to new structure
exports.NegotiationFieldsV0 = SingleNegotiationFields; // V0 was empty, now maps to Single
exports.NegotiationFieldsV1 = SingleNegotiationFields; // V1 had rounding intervals
exports.NegotiationFieldsV2 = DisjointNegotiationFields; // V2 had list of fields
//# sourceMappingURL=NegotiationFields.js.map