import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
import * as __typia_transform__accessExpressionAsString from "typia/lib/internal/_accessExpressionAsString.js";
import { createAssertEquals, createIs } from 'typia';
import { assertKeetaAnchorCertificateRequiredErrorJSONProperties } from './error.generated.js';
/**
 * Lazy-loaded error classes to avoid circular dependencies
 * The classes are loaded on first use
 */
let ERROR_CLASS_MAPPING = null;
async function getErrorClassMapping() {
    if (ERROR_CLASS_MAPPING) {
        return (ERROR_CLASS_MAPPING);
    }
    const ERROR_CLASSES = [
        /*
         * We purposefully leave out KeetaAnchorError here since it
         * is the base error class and could cause circular resolution
         */
        // eslint-disable-next-line @typescript-eslint/no-use-before-define
        KeetaAnchorUserError, KeetaAnchorUserValidationError, KeetaAnchorCertificateRequiredError
    ];
    // Dynamically import errors to avoid circular dependencies
    const importPromises = await Promise.all([
        import('../services/kyc/common.js'),
        import('../services/fx/common.js'),
        import('../services/asset-movement/common.js'),
        import('../services/storage/common.js'),
        import('../services/username/common.js')
    ]);
    for (const module of importPromises) {
        const classes = Object.values(module.Errors);
        ERROR_CLASSES.push(...classes);
    }
    const mapping = {};
    for (const errorClass of ERROR_CLASSES) {
        mapping[errorClass.name] = errorClass.fromJSON.bind(errorClass);
    }
    ERROR_CLASS_MAPPING = mapping;
    return (mapping);
}
/**
 * Base error class for all Keeta Anchor errors
 */
export class KeetaAnchorError extends Error {
    static name = 'KeetaAnchorError';
    #name;
    #statusCode = 400;
    #retryable = false;
    keetaAnchorErrorObjectTypeID;
    static keetaAnchorErrorObjectTypeID = '5d7f1578-e887-4104-bab0-4115ae33b08f';
    userError = false;
    logLevel = 'ERROR';
    get name() {
        return (this.#name);
    }
    set name(value) {
        this.#name = value;
    }
    get statusCode() {
        return (this.#statusCode);
    }
    set statusCode(value) {
        this.#statusCode = value;
    }
    get retryable() {
        return (this.#retryable);
    }
    set retryable(value) {
        this.#retryable = value;
    }
    constructor(message) {
        super(message);
        // Need to cast to access the static name property from the constructor
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
        this.#name = this.constructor.name;
        Object.defineProperty(this, 'keetaAnchorErrorObjectTypeID', {
            value: KeetaAnchorError.keetaAnchorErrorObjectTypeID,
            enumerable: false
        });
    }
    /**
     * Protected method to restore error properties from JSON
     * This allows subclasses to properly restore properties without using any
     */
    restoreFromJSON(other) {
        // Restore statusCode if present
        if ('statusCode' in other) {
            if (typeof other.statusCode !== 'number') {
                throw (new TypeError('Invalid statusCode: expected number'));
            }
            this.statusCode = other.statusCode;
        }
        // Restore retryable if present
        if ('retryable' in other) {
            if (typeof other.retryable !== 'boolean') {
                throw (new TypeError('Invalid retryable: expected boolean'));
            }
            this.retryable = other.retryable;
        }
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'keetaAnchorErrorObjectTypeID', KeetaAnchorError.keetaAnchorErrorObjectTypeID));
    }
    asErrorResponse(contentType, message) {
        message ??= 'Internal error';
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ...this.toJSON(),
                statusCode: undefined
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        let message = 'Internal error';
        if (this.userError) {
            message = this.message;
        }
        return ({
            ok: false,
            retryable: this.retryable,
            error: message,
            name: this.#name,
            statusCode: this.statusCode
        });
    }
    static hasPropWithValue(input, prop, value) {
        if (typeof input !== 'object' || input === null) {
            return (false);
        }
        if (!(prop in input)) {
            return (false);
        }
        // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
        const inputValue = input[prop];
        if (inputValue !== value) {
            return (false);
        }
        return (true);
    }
    /**
     * Extract common error properties from JSON input
     * This validates the structure and extracts properties needed for construction
     */
    static extractErrorProperties(input, expectedClass) {
        if (!this.hasPropWithValue(input, 'ok', false)) {
            throw (new Error('Invalid error JSON object'));
        }
        if (typeof input !== 'object' || input === null) {
            throw (new Error('Invalid error JSON object'));
        }
        // Verify the name matches if an expected class is provided
        if (expectedClass && 'name' in input && input.name !== expectedClass.name) {
            throw (new Error(`Error name mismatch: expected ${expectedClass.name}, got ${input.name}`));
        }
        // Extract error message
        let message = 'Internal error';
        if ('error' in input && typeof input.error === 'string') {
            message = input.error;
        }
        // Extract other properties
        const other = {};
        for (const key in input) {
            if (key !== 'error' && key !== 'ok') {
                // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
                other[key] = input[key];
            }
        }
        return ({ message, other });
    }
    static async fromJSON(input) {
        // Try to use the deserializer mapping if available for subclasses
        if (typeof input !== 'object' || input === null) {
            throw (new Error('Invalid error JSON object'));
        }
        if (!('ok' in input) || input.ok !== false) {
            throw (new Error('Invalid error JSON object: expected ok: false'));
        }
        // Check if there's a specific error class name
        if ('name' in input && typeof input.name === 'string') {
            if (input.name === 'KeetaAnchorError') {
                const { message, other } = KeetaAnchorError.extractErrorProperties(input, this);
                const error = new this(message);
                error.restoreFromJSON(other);
                return (error);
            }
            const mapping = await getErrorClassMapping();
            const deserializer = mapping[input.name];
            if (deserializer) {
                return (await deserializer(input));
            }
        }
        throw (new Error('Invalid error JSON object: unknown error class'));
    }
}
/**
 * User-facing error class that extends KeetaAnchorError
 */
export class KeetaAnchorUserError extends KeetaAnchorError {
    static name = 'KeetaAnchorUserError';
    keetaAnchorUserErrorObjectTypeID;
    static keetaAnchorUserErrorObjectTypeID = 'a1e64819-14b6-45ac-a1ec-b9c0bdd51e7b';
    userError = true;
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'keetaAnchorUserErrorObjectTypeID', KeetaAnchorUserError.keetaAnchorUserErrorObjectTypeID));
    }
    constructor(message) {
        super(message);
        Object.defineProperty(this, 'keetaAnchorUserErrorObjectTypeID', {
            value: KeetaAnchorUserError.keetaAnchorUserErrorObjectTypeID,
            enumerable: false
        });
    }
    asErrorResponse(contentType) {
        return (super.asErrorResponse(contentType, this.message));
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        const error = new this(message);
        error.restoreFromJSON(other);
        return (error);
    }
}
const assertKeetaAnchorUserValidationErrorDetails = (() => { const _io0 = (input, _exceptionable = true) => Array.isArray(input.fields) && input.fields.every((elem, _index1) => "object" === typeof elem && null !== elem && _io1(elem, true && _exceptionable)) && (1 === Object.keys(input).length || Object.keys(input).every(key => {
    if (["fields"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return false;
})); const _io1 = (input, _exceptionable = true) => (undefined === input.path || "string" === typeof input.path) && "string" === typeof input.message && (undefined === input.allowedValues || Array.isArray(input.allowedValues) && input.allowedValues.every((elem, _index2) => "string" === typeof elem)) && (undefined === input.expected || "string" === typeof input.expected) && true && (undefined === input.valueRules || "object" === typeof input.valueRules && null !== input.valueRules && false === Array.isArray(input.valueRules) && _io2(input.valueRules, true && _exceptionable)) && (1 === Object.keys(input).length || Object.keys(input).every(key => {
    if (["path", "message", "allowedValues", "expected", "receivedValue", "valueRules"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return false;
})); const _io2 = (input, _exceptionable = true) => (undefined === input.minimum || "string" === typeof input.minimum) && (undefined === input.maximum || "string" === typeof input.maximum) && (0 === Object.keys(input).length || Object.keys(input).every(key => {
    if (["minimum", "maximum"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return false;
})); const _ao0 = (input, _path, _exceptionable = true) => ((Array.isArray(input.fields) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".fields",
    expected: "Array<__type>",
    value: input.fields
}, _errorFactory)) && input.fields.every((elem, _index3) => ("object" === typeof elem && null !== elem || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".fields[" + _index3 + "]",
    expected: "__type",
    value: elem
}, _errorFactory)) && _ao1(elem, _path + ".fields[" + _index3 + "]", true && _exceptionable) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".fields[" + _index3 + "]",
    expected: "__type",
    value: elem
}, _errorFactory)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".fields",
    expected: "Array<__type>",
    value: input.fields
}, _errorFactory)) && (1 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
    if (["fields"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return __typia_transform__assertGuard._assertGuard(_exceptionable, {
        method: "createAssertEquals",
        path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
        expected: "undefined",
        value: value
    }, _errorFactory);
}))); const _ao1 = (input, _path, _exceptionable = true) => (undefined === input.path || "string" === typeof input.path || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".path",
    expected: "(string | undefined)",
    value: input.path
}, _errorFactory)) && ("string" === typeof input.message || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".message",
    expected: "string",
    value: input.message
}, _errorFactory)) && (undefined === input.allowedValues || (Array.isArray(input.allowedValues) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".allowedValues",
    expected: "(Array<string> | undefined)",
    value: input.allowedValues
}, _errorFactory)) && input.allowedValues.every((elem, _index4) => "string" === typeof elem || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".allowedValues[" + _index4 + "]",
    expected: "string",
    value: elem
}, _errorFactory)) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".allowedValues",
    expected: "(Array<string> | undefined)",
    value: input.allowedValues
}, _errorFactory)) && (undefined === input.expected || "string" === typeof input.expected || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".expected",
    expected: "(string | undefined)",
    value: input.expected
}, _errorFactory)) && true && (undefined === input.valueRules || ("object" === typeof input.valueRules && null !== input.valueRules && false === Array.isArray(input.valueRules) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".valueRules",
    expected: "(__type.o1 | undefined)",
    value: input.valueRules
}, _errorFactory)) && _ao2(input.valueRules, _path + ".valueRules", true && _exceptionable) || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".valueRules",
    expected: "(__type.o1 | undefined)",
    value: input.valueRules
}, _errorFactory)) && (1 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
    if (["path", "message", "allowedValues", "expected", "receivedValue", "valueRules"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return __typia_transform__assertGuard._assertGuard(_exceptionable, {
        method: "createAssertEquals",
        path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
        expected: "undefined",
        value: value
    }, _errorFactory);
}))); const _ao2 = (input, _path, _exceptionable = true) => (undefined === input.minimum || "string" === typeof input.minimum || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".minimum",
    expected: "(string | undefined)",
    value: input.minimum
}, _errorFactory)) && (undefined === input.maximum || "string" === typeof input.maximum || __typia_transform__assertGuard._assertGuard(_exceptionable, {
    method: "createAssertEquals",
    path: _path + ".maximum",
    expected: "(string | undefined)",
    value: input.maximum
}, _errorFactory)) && (0 === Object.keys(input).length || (false === _exceptionable || Object.keys(input).every(key => {
    if (["minimum", "maximum"].some(prop => key === prop))
        return true;
    const value = input[key];
    if (undefined === value)
        return true;
    return __typia_transform__assertGuard._assertGuard(_exceptionable, {
        method: "createAssertEquals",
        path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key),
        expected: "undefined",
        value: value
    }, _errorFactory);
}))); const __is = (input, _exceptionable = true) => "object" === typeof input && null !== input && _io0(input, true); let _errorFactory; return (input, errorFactory) => {
    if (false === __is(input)) {
        _errorFactory = errorFactory;
        ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || __typia_transform__assertGuard._assertGuard(true, {
            method: "createAssertEquals",
            path: _path + "",
            expected: "KeetaAnchorUserValidationErrorDetails",
            value: input
        }, _errorFactory)) && _ao0(input, _path + "", true) || __typia_transform__assertGuard._assertGuard(true, {
            method: "createAssertEquals",
            path: _path + "",
            expected: "KeetaAnchorUserValidationErrorDetails",
            value: input
        }, _errorFactory))(input, "$input", true);
    }
    return input;
}; })();
const isTypeGuardErrorLike = (() => { const _io0 = input => true && (undefined === input.path || "string" === typeof input.path) && "string" === typeof input.expected; return input => "object" === typeof input && null !== input && _io0(input); })();
export class KeetaAnchorUserValidationError extends KeetaAnchorUserError {
    static isTypeGuardErrorLike = isTypeGuardErrorLike;
    static name = 'KeetaAnchorUserValidationError';
    KeetaAnchorUserValidationErrorObjectTypeID;
    static KeetaAnchorUserValidationErrorObjectTypeID = '5fa46799-48b8-4cf2-a3de-9c01418d3ba0';
    userError = true;
    fields;
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAnchorUserValidationErrorObjectTypeID', KeetaAnchorUserValidationError.KeetaAnchorUserValidationErrorObjectTypeID));
    }
    constructor(args, message) {
        super(message ?? `Validation error on fields ${args.fields.map((f) => f.path).join(', ')}`);
        Object.defineProperty(this, 'KeetaAnchorUserValidationErrorObjectTypeID', {
            value: KeetaAnchorUserValidationError.KeetaAnchorUserValidationErrorObjectTypeID,
            enumerable: false
        });
        this.fields = args.fields;
    }
    get statusCode() {
        return (400);
    }
    asErrorResponse(contentType) {
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                data: { fields: this.fields },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            fields: this.fields
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAnchorUserValidationError JSON: missing data property'));
        }
        const parsed = assertKeetaAnchorUserValidationErrorDetails(other.data);
        const error = new this({ fields: parsed.fields }, message);
        error.restoreFromJSON(other);
        return (error);
    }
    static fromTypeGuardError(input, message) {
        let asArr;
        if (Array.isArray(input)) {
            asArr = input;
        }
        else {
            asArr = [input];
        }
        return (new this({
            fields: asArr.map(function (single) {
                let path;
                if (single.path !== undefined) {
                    const split = single.path.split('.');
                    if (split[0] === '$input') {
                        split.shift();
                    }
                    if (split.length > 0) {
                        path = split.join('.');
                    }
                }
                return ({
                    path,
                    message: message ?? 'Invalid value',
                    expected: single.expected,
                    receivedValue: single.value
                });
            })
        }, message));
    }
}
export class KeetaAnchorCertificateRequiredError extends KeetaAnchorUserError {
    static name = 'KeetaAnchorCertificateRequiredError';
    KeetaAnchorCertificateRequiredErrorObjectTypeID;
    static KeetaAnchorCertificateRequiredErrorObjectTypeID = 'b8c5b6df-2f4d-4f60-9d6c-2f4d8a6b1f01';
    acceptedIssuers;
    kind;
    constructor(args, message) {
        super(message ?? KeetaAnchorCertificateRequiredError.defaultMessage(args.kind));
        if (args.kind === 'missing') {
            this.statusCode = 401;
        }
        else {
            this.statusCode = 403;
        }
        Object.defineProperty(this, 'KeetaAnchorCertificateRequiredErrorObjectTypeID', {
            value: KeetaAnchorCertificateRequiredError.KeetaAnchorCertificateRequiredErrorObjectTypeID,
            enumerable: false
        });
        this.acceptedIssuers = args.acceptedIssuers;
        this.kind = args.kind;
    }
    static defaultMessage(kind) {
        if (kind === 'missing') {
            return ('No certificate has been published for the signing account');
        }
        return ('Published certificates do not chain to an accepted issuer');
    }
    static isInstance(input) {
        return (this.hasPropWithValue(input, 'KeetaAnchorCertificateRequiredErrorObjectTypeID', KeetaAnchorCertificateRequiredError.KeetaAnchorCertificateRequiredErrorObjectTypeID));
    }
    asErrorResponse(contentType) {
        let message = this.message;
        if (contentType === 'application/json') {
            message = JSON.stringify({
                ok: false,
                name: this.name,
                data: { acceptedIssuers: this.acceptedIssuers, kind: this.kind },
                error: this.message
            });
        }
        return ({
            error: message,
            statusCode: this.statusCode,
            contentType: contentType
        });
    }
    toJSON() {
        return ({
            ...super.toJSON(),
            acceptedIssuers: this.acceptedIssuers,
            kind: this.kind
        });
    }
    static async fromJSON(input) {
        const { message, other } = this.extractErrorProperties(input, this);
        if (!('data' in other)) {
            throw (new Error('Invalid KeetaAnchorCertificateRequiredError JSON: missing data property'));
        }
        const parsed = assertKeetaAnchorCertificateRequiredErrorJSONProperties(other.data);
        const error = new this({ acceptedIssuers: parsed.acceptedIssuers, kind: parsed.kind }, message);
        error.restoreFromJSON(other);
        return (error);
    }
}
//# sourceMappingURL=error.js.map