// SPDX-License-Identifier: Apache-2.0
import BaseError, { ErrorCode } from "../../../../../../core/error/BaseError";
import { ClearingActivated } from "../ClearingActivated";
import { InsufficientAllowance } from "../InsufficientAllowance";
import { InvalidPartition } from "../InvalidPartition";
import { InsufficientBalance } from "../InsufficientBalance";
import { SecurityPaused } from "../SecurityPaused";
import { EIP1066_CODES } from "../codes";
import { ethers } from "ethers";
import { ZeroAddressNotAllowed } from "../ZeroAddressNotAllowed";
import { AccountBlocked } from "../AccountBlocked";
import { ComplianceNotAllowed } from "../ComplianceNotAllowed";
import { InvalidKycStatus } from "../InvalidKycStatus";
import { WalletRecovered } from "../WalletRecovered";
import { AddressNotVerified } from "../AddressNotVerified";
export class ContractsErrorMapper {
    static mapError(errorCode, reason) {
        const normalizedErrorCode = errorCode.toLowerCase();
        const normalizedReason = reason.toLowerCase().slice(0, 10);
        const combinedKey = `${normalizedErrorCode}:${normalizedReason}`;
        const errorFactory = this.ERROR_MAPPINGS.get(combinedKey) || this.ERROR_MAPPINGS.get(normalizedErrorCode);
        return (errorFactory?.() ||
            new BaseError(ErrorCode.Unexpected, `Unexpected error code: ${errorCode} with reason: ${reason}`));
    }
    static createSelector(signature) {
        return ethers.keccak256(ethers.toUtf8Bytes(signature)).slice(0, 10);
    }
    static SELECTORS = {
        zeroAddressNotAllowed: this.createSelector("ZeroAddressNotAllowed()"),
        accountIsBlocked: this.createSelector("AccountIsBlocked(address)"),
        tokenIsPaused: this.createSelector("TokenIsPaused()"),
        clearingIsActivated: this.createSelector("ClearingIsActivated()"),
        complianceNotAllowed: this.createSelector("ComplianceNotAllowed()"),
        invalidKycStatus: this.createSelector("InvalidKycStatus()"),
        addressNotVerified: this.createSelector("AddressNotVerified()"),
        walletRecovered: this.createSelector("WalletRecovered()"),
        insufficientAllowance: this.createSelector("InsufficientAllowance(address,address)"),
        invalidPartition: this.createSelector("InvalidPartition(address,bytes32)"),
        insufficientBalance: this.createSelector("InsufficientBalance(address,uint256,uint256,bytes32)"),
    };
    static ERROR_MAPPINGS = new Map([
        [`${EIP1066_CODES.PAUSED}:${ContractsErrorMapper.SELECTORS.tokenIsPaused}`, () => new SecurityPaused()],
        [`${EIP1066_CODES.PAUSED}`, () => new SecurityPaused()],
        [
            `${EIP1066_CODES.NOT_FOUND_UNEQUAL_OR_OUT_OF_RANGE}:${ContractsErrorMapper.SELECTORS.zeroAddressNotAllowed}`,
            () => new ZeroAddressNotAllowed(),
        ],
        [
            `${EIP1066_CODES.NOT_FOUND_UNEQUAL_OR_OUT_OF_RANGE}:${ContractsErrorMapper.SELECTORS.accountIsBlocked}`,
            () => new AccountBlocked(),
        ],
        [
            `${EIP1066_CODES.UNAVAILABLE}:${ContractsErrorMapper.SELECTORS.clearingIsActivated}`,
            () => new ClearingActivated(),
        ],
        [
            `${EIP1066_CODES.DISALLOWED_OR_STOP}:${ContractsErrorMapper.SELECTORS.accountIsBlocked}`,
            () => new AccountBlocked(),
        ],
        [
            `${EIP1066_CODES.DISALLOWED_OR_STOP}:${ContractsErrorMapper.SELECTORS.complianceNotAllowed}`,
            () => new ComplianceNotAllowed(),
        ],
        [
            `${EIP1066_CODES.DISALLOWED_OR_STOP}:${ContractsErrorMapper.SELECTORS.invalidKycStatus}`,
            () => new InvalidKycStatus(),
        ],
        [
            `${EIP1066_CODES.DISALLOWED_OR_STOP}:${ContractsErrorMapper.SELECTORS.addressNotVerified}`,
            () => new AddressNotVerified(),
        ],
        [
            `${EIP1066_CODES.REVOKED_OR_BANNED}:${ContractsErrorMapper.SELECTORS.walletRecovered}`,
            () => new WalletRecovered(),
        ],
        [
            `${EIP1066_CODES.INSUFFICIENT_FUNDS}:${ContractsErrorMapper.SELECTORS.insufficientAllowance}`,
            () => new InsufficientAllowance(),
        ],
        [
            `${EIP1066_CODES.INSUFFICIENT_FUNDS}:${ContractsErrorMapper.SELECTORS.invalidPartition}`,
            () => new InvalidPartition(),
        ],
        [
            `${EIP1066_CODES.INSUFFICIENT_FUNDS}:${ContractsErrorMapper.SELECTORS.insufficientBalance}`,
            () => new InsufficientBalance(),
        ],
        [
            `${EIP1066_CODES.SUCCESS}`,
            () => new BaseError(ErrorCode.Unexpected, "Unexpected success code in error context"),
        ],
    ]);
}
