// This file was autogenerated by the `uniffi-bindgen-gecko-js` crate.
// Trust me, you don't want to mess with it!

import {
  ArrayBufferDataStream,
  FfiConverter,
  FfiConverterArrayBuffer,
  FfiConverterInt8,
  FfiConverterUInt8,
  FfiConverterInt16,
  FfiConverterUInt16,
  FfiConverterInt32,
  FfiConverterUInt32,
  FfiConverterInt64,
  FfiConverterUInt64,
  FfiConverterFloat32,
  FfiConverterFloat64,
  FfiConverterBoolean,
  FfiConverterBytes,
  FfiConverterString,
  UniFFICallbackHandler,
  UniFFICallbackMethodHandler,
  UniFFIError,
  UniFFIInternalError,
  UniFFITypeError,
  constructUniffiObject,
  handleRustResult,
  uniffiObjectPtr,
} from "moz-src:///toolkit/components/uniffi-js/js/UniFFI.sys.mjs";

// Objects intended to be used in the unit tests
export var UnitTestObjs = {
    uniffiObjectPtr,
};





/**
 * BreachAlertDismissal
 */
export class BreachAlertDismissal {
    constructor(
        {
            breachName, 
            timeDismissed
        } = {
            breachName: undefined, 
            timeDismissed: undefined
        }
    ) {
        try {
            FfiConverterString.checkType(breachName)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("breachName");
            }
            throw e;
        }
        try {
            FfiConverterInt64.checkType(timeDismissed)
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart("timeDismissed");
            }
            throw e;
        }
        /**
         * The HIBP breach name. HIBP calls this a "name" rather than an ID, but it is unique
         * and serves as the breach's stable identifier.
         * @type {string}
         */
        this.breachName = breachName;
        /**
         * Unix timestamp in milliseconds of when the breach alert was last dismissed.
         * @type {number}
         */
        this.timeDismissed = timeDismissed;
    }

    equals(other) {
        return (
            this.breachName == other.breachName
            && this.timeDismissed == other.timeDismissed
        )
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeBreachAlertDismissal extends FfiConverterArrayBuffer {
    static read(dataStream) {
        return new BreachAlertDismissal({
            breachName: FfiConverterString.read(dataStream),
            timeDismissed: FfiConverterInt64.read(dataStream),
        });
    }
    static write(dataStream, value) {
        FfiConverterString.write(dataStream, value.breachName);
        FfiConverterInt64.write(dataStream, value.timeDismissed);
    }

    static computeSize(value) {
        let totalSize = 0;
        totalSize += FfiConverterString.computeSize(value.breachName);
        totalSize += FfiConverterInt64.computeSize(value.timeDismissed);
        return totalSize
    }

    static checkType(value) {
        super.checkType(value);
        if (!(value instanceof BreachAlertDismissal)) {
            throw new UniFFITypeError(`Expected 'BreachAlertDismissal', found '${typeof value}'`);
        }
        try {
            FfiConverterString.checkType(value.breachName);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".breachName");
            }
            throw e;
        }
        try {
            FfiConverterInt64.checkType(value.timeDismissed);
        } catch (e) {
            if (e instanceof UniFFITypeError) {
                e.addItemDescriptionPart(".timeDismissed");
            }
            throw e;
        }
    }
}

/**
 * Errors returned via the public (FFI) interface.
 */
export class BreachAlertsApiError extends Error {}


/**
 * Unexpected
 */
export class Unexpected extends BreachAlertsApiError {

    constructor(
        reason,
        ...params
    ) {
        const message = `reason: ${ reason }`;
        super(message, ...params);
        this.reason = reason;
    }
    toString() {
        return `Unexpected: ${super.toString()}`
    }
}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeBreachAlertsApiError extends FfiConverterArrayBuffer {
    static read(dataStream) {
        switch (dataStream.readInt32()) {
            case 1:
                return new Unexpected(
                    FfiConverterString.read(dataStream)
                    );
            default:
                throw new UniFFITypeError("Unknown BreachAlertsApiError variant");
        }
    }
    static computeSize(value) {
        // Size of the Int indicating the variant
        let totalSize = 4;
        if (value instanceof Unexpected) {
            totalSize += FfiConverterString.computeSize(value.reason);
            return totalSize;
        }
        throw new UniFFITypeError("Unknown BreachAlertsApiError variant");
    }
    static write(dataStream, value) {
        if (value instanceof Unexpected) {
            dataStream.writeInt32(1);
            FfiConverterString.write(dataStream, value.reason);
            return;
        }
        throw new UniFFITypeError("Unknown BreachAlertsApiError variant");
    }

    static errorClass = BreachAlertsApiError;
}
// Export the FFIConverter object to make external types work.
export class FfiConverterSequenceString extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const arr = [];
        for (let i = 0; i < len; i++) {
            arr.push(FfiConverterString.read(dataStream));
        }
        return arr;
    }

    static write(dataStream, value) {
        dataStream.writeInt32(value.length);
        value.forEach((innerValue) => {
            FfiConverterString.write(dataStream, innerValue);
        })
    }

    static computeSize(value) {
        // The size of the length
        let size = 4;
        for (const innerValue of value) {
            size += FfiConverterString.computeSize(innerValue);
        }
        return size;
    }

    static checkType(value) {
        if (!Array.isArray(value)) {
            throw new UniFFITypeError(`${value} is not an array`);
        }
        value.forEach((innerValue, idx) => {
            try {
                FfiConverterString.checkType(innerValue);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${idx}]`);
                }
                throw e;
            }
        })
    }
}
// Export the FFIConverter object to make external types work.
export class FfiConverterSequenceTypeBreachAlertDismissal extends FfiConverterArrayBuffer {
    static read(dataStream) {
        const len = dataStream.readInt32();
        const arr = [];
        for (let i = 0; i < len; i++) {
            arr.push(FfiConverterTypeBreachAlertDismissal.read(dataStream));
        }
        return arr;
    }

    static write(dataStream, value) {
        dataStream.writeInt32(value.length);
        value.forEach((innerValue) => {
            FfiConverterTypeBreachAlertDismissal.write(dataStream, innerValue);
        })
    }

    static computeSize(value) {
        // The size of the length
        let size = 4;
        for (const innerValue of value) {
            size += FfiConverterTypeBreachAlertDismissal.computeSize(innerValue);
        }
        return size;
    }

    static checkType(value) {
        if (!Array.isArray(value)) {
            throw new UniFFITypeError(`${value} is not an array`);
        }
        value.forEach((innerValue, idx) => {
            try {
                FfiConverterTypeBreachAlertDismissal.checkType(innerValue);
            } catch (e) {
                if (e instanceof UniFFITypeError) {
                    e.addItemDescriptionPart(`[${idx}]`);
                }
                throw e;
            }
        })
    }
}

/**
 * A store for managing breach alert data. It manages an underlying
 * database connection and exposes methods for reading and writing
 * breach alert dismissals.
 * 
 * An application should create only one store, and manage the instance
 * as a singleton.
 */
export class BreachAlertsStoreInterface {
    /**
     * clearAllBreachAlertDismissals
     */
    async clearAllBreachAlertDismissals() {
      throw Error("clearAllBreachAlertDismissals not implemented");
    }
    /**
     * clearBreachAlertDismissals
     * @param {Array.<string>} breachNames
     */
    async clearBreachAlertDismissals(
        breachNames) {
      throw Error("clearBreachAlertDismissals not implemented");
    }
    /**
     * close
     */
    async close() {
      throw Error("close not implemented");
    }
    /**
     * getBreachAlertDismissals
     * @param {Array.<string>} breachNames
     * @returns {Promise<Array.<BreachAlertDismissal>>}}
     */
    async getBreachAlertDismissals(
        breachNames) {
      throw Error("getBreachAlertDismissals not implemented");
    }
    /**
     * setBreachAlertDismissals
     * @param {Array.<BreachAlertDismissal>} dismissals
     */
    async setBreachAlertDismissals(
        dismissals) {
      throw Error("setBreachAlertDismissals not implemented");
    }

}

/**
 * A store for managing breach alert data. It manages an underlying
 * database connection and exposes methods for reading and writing
 * breach alert dismissals.
 * 
 * An application should create only one store, and manage the instance
 * as a singleton.
 */
export class BreachAlertsStore extends BreachAlertsStoreInterface {
    // Use `init` to instantiate this class.
    // DO NOT USE THIS CONSTRUCTOR DIRECTLY
    constructor(opts) {
        super();
        if (!Object.prototype.hasOwnProperty.call(opts, constructUniffiObject)) {
            throw new UniFFIError("Attempting to construct an int using the JavaScript constructor directly" +
            "Please use a UDL defined constructor, or the init function for the primary constructor")
        }
        if (!(opts[constructUniffiObject] instanceof UniFFIPointer)) {
            throw new UniFFIError("Attempting to create a UniFFI object with a pointer that is not an instance of UniFFIPointer")
        }
        this[uniffiObjectPtr] = opts[constructUniffiObject];
    }
    /**
     * newStore
     * @param {string} dbPath
     * @returns {Promise<BreachAlertsStore>}}
     */
    static async newStore(
        dbPath) {
       
        FfiConverterString.checkType(dbPath);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            1, // uniffi_breach_alerts_fn_constructor_breachalertsstore_new_store
            FfiConverterString.lower(dbPath),
        )
        return handleRustResult(
            result,
            FfiConverterTypeBreachAlertsStore.lift.bind(FfiConverterTypeBreachAlertsStore),
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

    /**
     * clearAllBreachAlertDismissals
     */
    async clearAllBreachAlertDismissals() {
       
        const result = await UniFFIScaffolding.callAsyncWrapper(
            2, // uniffi_breach_alerts_fn_method_breachalertsstore_clear_all_breach_alert_dismissals
            FfiConverterTypeBreachAlertsStore.lowerReceiver(this),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

    /**
     * clearBreachAlertDismissals
     * @param {Array.<string>} breachNames
     */
    async clearBreachAlertDismissals(
        breachNames) {
       
        FfiConverterSequenceString.checkType(breachNames);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            3, // uniffi_breach_alerts_fn_method_breachalertsstore_clear_breach_alert_dismissals
            FfiConverterTypeBreachAlertsStore.lowerReceiver(this),
            FfiConverterSequenceString.lower(breachNames),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

    /**
     * close
     */
    async close() {
       
        const result = await UniFFIScaffolding.callAsyncWrapper(
            4, // uniffi_breach_alerts_fn_method_breachalertsstore_close
            FfiConverterTypeBreachAlertsStore.lowerReceiver(this),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

    /**
     * getBreachAlertDismissals
     * @param {Array.<string>} breachNames
     * @returns {Promise<Array.<BreachAlertDismissal>>}}
     */
    async getBreachAlertDismissals(
        breachNames) {
       
        FfiConverterSequenceString.checkType(breachNames);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            5, // uniffi_breach_alerts_fn_method_breachalertsstore_get_breach_alert_dismissals
            FfiConverterTypeBreachAlertsStore.lowerReceiver(this),
            FfiConverterSequenceString.lower(breachNames),
        )
        return handleRustResult(
            result,
            FfiConverterSequenceTypeBreachAlertDismissal.lift.bind(FfiConverterSequenceTypeBreachAlertDismissal),
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

    /**
     * setBreachAlertDismissals
     * @param {Array.<BreachAlertDismissal>} dismissals
     */
    async setBreachAlertDismissals(
        dismissals) {
       
        FfiConverterSequenceTypeBreachAlertDismissal.checkType(dismissals);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            6, // uniffi_breach_alerts_fn_method_breachalertsstore_set_breach_alert_dismissals
            FfiConverterTypeBreachAlertsStore.lowerReceiver(this),
            FfiConverterSequenceTypeBreachAlertDismissal.lower(dismissals),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeBreachAlertsApiError.lift.bind(FfiConverterTypeBreachAlertsApiError),
        )
    }

}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeBreachAlertsStore extends FfiConverter {
    static lift(value) {
        const opts = {};
        opts[constructUniffiObject] = value;
        return new BreachAlertsStore(opts);
    }

    static lower(value) {
        const ptr = value[uniffiObjectPtr];
        if (!(ptr instanceof UniFFIPointer)) {
            throw new UniFFITypeError("Object is not a 'BreachAlertsStore' instance");
        }
        return ptr;
    }

    static lowerReceiver(value) {
        // This works exactly the same as lower for non-trait interfaces
        return this.lower(value);
    }

    static read(dataStream) {
        return this.lift(dataStream.readPointer(1));
    }

    static write(dataStream, value) {
        dataStream.writePointer(1, this.lower(value));
    }

    static computeSize(value) {
        return 8;
    }
}



