"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBaseMatchers = void 0;
const tslib_1 = require("tslib");
const aws_sdk_client_mock_1 = require("aws-sdk-client-mock");
const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
function processMatch(args) {
    const { ctx, mockClient, command, check, message } = args;
    (0, node_assert_1.default)(mockClient instanceof aws_sdk_client_mock_1.AwsStub, 'The actual must be a client mock instance');
    if (command) {
        (0, node_assert_1.default)(typeof command === 'function' &&
            typeof command.name === 'string' &&
            command.name.length > 0, 'Command must be valid AWS SDK Command');
    }
    const calls = mockClient.calls();
    const commandCalls = command ? mockClient.commandCalls(command) : [];
    const { pass, data } = check({ calls, commandCalls });
    const msg = () => {
        var _a;
        const cmd = (_a = command === null || command === void 0 ? void 0 : command.name) !== null && _a !== void 0 ? _a : 'Any Command';
        const client = mockClient.clientName();
        return message({
            client,
            cmd,
            data,
            calls,
            commandCalls,
            notPrefix: ctx.isNot ? 'not ' : '',
            ctxUtils: ctx.utils,
        });
    };
    return { pass, message: msg };
}
const ensureNoOtherArgs = (args) => {
    (0, node_assert_1.default)(args.length === 0, 'Too many matcher arguments');
};
function createBaseMatchers(errorMsg, objectContaining) {
    return {
        toHaveReceivedCommand(mockClient, command, ...other) {
            ensureNoOtherArgs(other);
            return processMatch({
                ctx: this,
                mockClient,
                command,
                check: ({ commandCalls }) => ({
                    pass: commandCalls.length > 0,
                    data: undefined,
                }),
                message: errorMsg.toHaveReceivedCommand,
            });
        },
        toHaveReceivedCommandTimes(mockClient, command, expectedCalls, ...other) {
            ensureNoOtherArgs(other);
            return processMatch({
                ctx: this,
                mockClient,
                command,
                check: ({ commandCalls }) => ({
                    pass: commandCalls.length === expectedCalls,
                    data: undefined,
                }),
                message: errorMsg.toHaveReceivedCommandTimes(expectedCalls),
            });
        },
        toHaveReceivedCommandWith(mockClient, command, input, ...other) {
            ensureNoOtherArgs(other);
            return processMatch({
                ctx: this,
                mockClient,
                command,
                check: ({ commandCalls }) => {
                    const matchCount = commandCalls
                        .map((call) => call.args[0].input) // eslint-disable-line @typescript-eslint/no-unsafe-return
                        .map((received) => objectContaining(input).asymmetricMatch(received))
                        .reduce((acc, val) => acc + Number(val), 0);
                    return { pass: matchCount > 0, data: { matchCount } };
                },
                message: errorMsg.toHaveReceivedCommandWith(input),
            });
        },
        toHaveReceivedNthCommandWith(mockClient, call, command, input, ...other) {
            ensureNoOtherArgs(other);
            (0, node_assert_1.default)(call && typeof call === 'number' && call > 0, 'Call number must be a number greater than 0');
            return processMatch({
                ctx: this,
                mockClient,
                command,
                check: ({ calls }) => {
                    if (calls.length < call) {
                        return { pass: false, data: { received: undefined } };
                    }
                    const received = calls[call - 1].args[0];
                    let pass = false;
                    if (received instanceof command) {
                        pass = objectContaining(input).asymmetricMatch(received.input);
                    }
                    return {
                        pass,
                        data: { received },
                    };
                },
                message: errorMsg.toHaveReceivedNthCommandWith(call, input),
            });
        },
        toHaveReceivedNthSpecificCommandWith(mockClient, call, command, input, ...other) {
            ensureNoOtherArgs(other);
            (0, node_assert_1.default)(call && typeof call === 'number' && call > 0, 'Call number must be a number greater than 0');
            return processMatch({
                ctx: this,
                mockClient,
                command,
                check: ({ commandCalls }) => {
                    if (commandCalls.length < call) {
                        return { pass: false, data: { received: undefined } };
                    }
                    const received = commandCalls[call - 1].args[0];
                    let pass = false;
                    if (received instanceof command) {
                        pass = objectContaining(input).asymmetricMatch(received.input);
                    }
                    return {
                        pass,
                        data: { received },
                    };
                },
                message: errorMsg.toHaveReceivedNthSpecificCommandWith(call, input),
            });
        },
        toHaveReceivedAnyCommand(mockClient, ...other) {
            ensureNoOtherArgs(other);
            return processMatch({
                ctx: this,
                mockClient,
                check: ({ calls }) => ({ pass: calls.length > 0, data: undefined }),
                message: errorMsg.toHaveReceivedAnyCommand,
            });
        },
    };
}
exports.createBaseMatchers = createBaseMatchers;
//# sourceMappingURL=jestMatchers.js.map