// 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,
};




/**
 * ApiError
 */
export class ApiError extends Error {}


/**
 * Other
 */
export class Other extends ApiError {

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

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

    static errorClass = ApiError;
}



/**
 * Top-level API for the context_id component
 */
export class ContextIdComponentInterface {
    /**
     * Regenerate the context ID.
     */
    async forceRotation() {
      throw Error("forceRotation not implemented");
    }
    /**
     * Return the current context ID string.
     * @param {number} rotationDaysInS
     * @returns {Promise<string>}}
     */
    async request(
        rotationDaysInS) {
      throw Error("request not implemented");
    }
    /**
     * Unset the callbacks set during construction, and use a default
     * no-op ContextIdCallback instead.
     */
    async unsetCallback() {
      throw Error("unsetCallback not implemented");
    }

}

/**
 * Top-level API for the context_id component
 */
export class ContextIdComponent extends ContextIdComponentInterface {
    // 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];
    }
    /**
     * Construct a new [ContextIDComponent].
     * 
     * If no creation timestamp is provided, the current time will be used.
     * @param {string} initContextId
     * @param {number} creationTimestampS
     * @param {boolean} runningInTestAutomation
     * @param {ContextIdCallback} callback
     * @returns {ContextIdComponent}
     */
    static init(
        initContextId, 
        creationTimestampS, 
        runningInTestAutomation, 
        callback) {
       
        FfiConverterString.checkType(initContextId);
        FfiConverterInt64.checkType(creationTimestampS);
        FfiConverterBoolean.checkType(runningInTestAutomation);
        FfiConverterTypeContextIdCallback.checkType(callback);
        const result = UniFFIScaffolding.callSync(
            7, // uniffi_context_id_fn_constructor_contextidcomponent_new
            FfiConverterString.lower(initContextId),
            FfiConverterInt64.lower(creationTimestampS),
            FfiConverterBoolean.lower(runningInTestAutomation),
            FfiConverterTypeContextIdCallback.lower(callback),
        )
        return handleRustResult(
            result,
            FfiConverterTypeContextIDComponent.lift.bind(FfiConverterTypeContextIDComponent),
            null,
        )
    }

    /**
     * Regenerate the context ID.
     */
    async forceRotation() {
       
        const result = await UniFFIScaffolding.callAsyncWrapper(
            8, // uniffi_context_id_fn_method_contextidcomponent_force_rotation
            FfiConverterTypeContextIDComponent.lowerReceiver(this),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeApiError.lift.bind(FfiConverterTypeApiError),
        )
    }

    /**
     * Return the current context ID string.
     * @param {number} rotationDaysInS
     * @returns {Promise<string>}}
     */
    async request(
        rotationDaysInS) {
       
        FfiConverterUInt8.checkType(rotationDaysInS);
        const result = await UniFFIScaffolding.callAsyncWrapper(
            9, // uniffi_context_id_fn_method_contextidcomponent_request
            FfiConverterTypeContextIDComponent.lowerReceiver(this),
            FfiConverterUInt8.lower(rotationDaysInS),
        )
        return handleRustResult(
            result,
            FfiConverterString.lift.bind(FfiConverterString),
            FfiConverterTypeApiError.lift.bind(FfiConverterTypeApiError),
        )
    }

    /**
     * Unset the callbacks set during construction, and use a default
     * no-op ContextIdCallback instead.
     */
    async unsetCallback() {
       
        const result = await UniFFIScaffolding.callAsyncWrapper(
            10, // uniffi_context_id_fn_method_contextidcomponent_unset_callback
            FfiConverterTypeContextIDComponent.lowerReceiver(this),
        )
        return handleRustResult(
            result,
            (result) => undefined,
            FfiConverterTypeApiError.lift.bind(FfiConverterTypeApiError),
        )
    }

}

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

    static lower(value) {
        const ptr = value[uniffiObjectPtr];
        if (!(ptr instanceof UniFFIPointer)) {
            throw new UniFFITypeError("Object is not a 'ContextIdComponent' 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(2));
    }

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

    static computeSize(value) {
        return 8;
    }
}




/**
 * ContextIdCallback
 */
export class ContextIdCallback {
    /**
     * persist
     * @param {string} contextId
     * @param {number} creationDate
     */
    persist(
        contextId, 
        creationDate) {
      throw Error("persist not implemented");
    }
    /**
     * rotated
     * @param {string} oldContextId
     */
    rotated(
        oldContextId) {
      throw Error("rotated not implemented");
    }

}

// Export the FFIConverter object to make external types work.
export class FfiConverterTypeContextIdCallback extends FfiConverter {
    static lower(callbackObj) {
        if (!(callbackObj instanceof ContextIdCallback)) {
            throw new UniFFITypeError("expected 'ContextIdCallback' subclass");
        }
        return uniffiCallbackHandlerContextIdContextIdCallback.storeCallbackObj(callbackObj)
    }

    static lift(handleId) {
        return uniffiCallbackHandlerContextIdContextIdCallback.takeCallbackObj(handleId)
    }

    static read(dataStream) {
        return this.lift(dataStream.readInt64())
    }

    static write(dataStream, callbackObj) {
        dataStream.writeInt64(this.lower(callbackObj))
    }

    static computeSize(callbackObj) {
        return 8;
    }
}
const uniffiCallbackHandlerContextIdContextIdCallback = new UniFFICallbackHandler(
    "ContextIdCallback",
    1,
    [
        new UniFFICallbackMethodHandler(
            "persist",
            [
                FfiConverterString,
                FfiConverterInt64,
            ],
            (result) => undefined,
            (e) => {
              throw e;
            }
        ),
        new UniFFICallbackMethodHandler(
            "rotated",
            [
                FfiConverterString,
            ],
            (result) => undefined,
            (e) => {
              throw e;
            }
        ),
    ]
);

// Allow the shutdown-related functionality to be tested in the unit tests
UnitTestObjs.uniffiCallbackHandlerContextIdContextIdCallback = uniffiCallbackHandlerContextIdContextIdCallback;


