import {Buffer} from 'node:buffer';
import test from 'ava';
import {execa, execaSync} from '../../index.js';
import {setFixtureDirectory} from '../helpers/fixtures-directory.js';
import {foobarString, foobarUint8Array, foobarBuffer} from '../helpers/input.js';
import {getOutputGenerator, convertTransformToFinal} from '../helpers/generator.js';

setFixtureDirectory();

// eslint-disable-next-line max-params
const testGeneratorReturnType = async (t, input, encoding, reject, objectMode, final, execaMethod) => {
	const fixtureName = reject ? 'noop-fd.js' : 'noop-fail.js';
	const {stdout} = await execaMethod(fixtureName, ['1', foobarString], {
		stdout: convertTransformToFinal(getOutputGenerator(input)(objectMode, true), final),
		encoding,
		reject,
	});
	const typeofChunk = Array.isArray(stdout) ? stdout[0] : stdout;
	const output = Buffer.from(typeofChunk, encoding === 'buffer' || objectMode ? undefined : encoding).toString();
	t.is(output, foobarString);
};

test('Generator can return string with default encoding', testGeneratorReturnType, foobarString, 'utf8', true, false, false, execa);
test('Generator can return Uint8Array with default encoding', testGeneratorReturnType, foobarUint8Array, 'utf8', true, false, false, execa);
test('Generator can return Buffer with default encoding', testGeneratorReturnType, foobarBuffer, 'utf8', true, false, false, execa);
test('Generator can return string with encoding "utf16le"', testGeneratorReturnType, foobarString, 'utf16le', true, false, false, execa);
test('Generator can return Uint8Array with encoding "utf16le"', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, false, false, execa);
test('Generator can return Buffer with encoding "utf16le"', testGeneratorReturnType, foobarBuffer, 'utf16le', true, false, false, execa);
test('Generator can return string with encoding "buffer"', testGeneratorReturnType, foobarString, 'buffer', true, false, false, execa);
test('Generator can return Uint8Array with encoding "buffer"', testGeneratorReturnType, foobarUint8Array, 'buffer', true, false, false, execa);
test('Generator can return Buffer with encoding "buffer"', testGeneratorReturnType, foobarBuffer, 'buffer', true, false, false, execa);
test('Generator can return string with encoding "hex"', testGeneratorReturnType, foobarString, 'hex', true, false, false, execa);
test('Generator can return Uint8Array with encoding "hex"', testGeneratorReturnType, foobarUint8Array, 'hex', true, false, false, execa);
test('Generator can return Buffer with encoding "hex"', testGeneratorReturnType, foobarBuffer, 'hex', true, false, false, execa);
test('Generator can return string with default encoding, failure', testGeneratorReturnType, foobarString, 'utf8', false, false, false, execa);
test('Generator can return Uint8Array with default encoding, failure', testGeneratorReturnType, foobarUint8Array, 'utf8', false, false, false, execa);
test('Generator can return string with encoding "utf16le", failure', testGeneratorReturnType, foobarString, 'utf16le', false, false, false, execa);
test('Generator can return Uint8Array with encoding "utf16le", failure', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, false, false, execa);
test('Generator can return string with encoding "buffer", failure', testGeneratorReturnType, foobarString, 'buffer', false, false, false, execa);
test('Generator can return Uint8Array with encoding "buffer", failure', testGeneratorReturnType, foobarUint8Array, 'buffer', false, false, false, execa);
test('Generator can return string with encoding "hex", failure', testGeneratorReturnType, foobarString, 'hex', false, false, false, execa);
test('Generator can return Uint8Array with encoding "hex", failure', testGeneratorReturnType, foobarUint8Array, 'hex', false, false, false, execa);
test('Generator can return string with default encoding, objectMode', testGeneratorReturnType, foobarString, 'utf8', true, true, false, execa);
test('Generator can return Uint8Array with default encoding, objectMode', testGeneratorReturnType, foobarUint8Array, 'utf8', true, true, false, execa);
test('Generator can return string with encoding "utf16le", objectMode', testGeneratorReturnType, foobarString, 'utf16le', true, true, false, execa);
test('Generator can return Uint8Array with encoding "utf16le", objectMode', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, true, false, execa);
test('Generator can return string with encoding "buffer", objectMode', testGeneratorReturnType, foobarString, 'buffer', true, true, false, execa);
test('Generator can return Uint8Array with encoding "buffer", objectMode', testGeneratorReturnType, foobarUint8Array, 'buffer', true, true, false, execa);
test('Generator can return string with encoding "hex", objectMode', testGeneratorReturnType, foobarString, 'hex', true, true, false, execa);
test('Generator can return Uint8Array with encoding "hex", objectMode', testGeneratorReturnType, foobarUint8Array, 'hex', true, true, false, execa);
test('Generator can return string with default encoding, objectMode, failure', testGeneratorReturnType, foobarString, 'utf8', false, true, false, execa);
test('Generator can return Uint8Array with default encoding, objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'utf8', false, true, false, execa);
test('Generator can return string with encoding "utf16le", objectMode, failure', testGeneratorReturnType, foobarString, 'utf16le', false, true, false, execa);
test('Generator can return Uint8Array with encoding "utf16le", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, true, false, execa);
test('Generator can return string with encoding "buffer", objectMode, failure', testGeneratorReturnType, foobarString, 'buffer', false, true, false, execa);
test('Generator can return Uint8Array with encoding "buffer", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'buffer', false, true, false, execa);
test('Generator can return string with encoding "hex", objectMode, failure', testGeneratorReturnType, foobarString, 'hex', false, true, false, execa);
test('Generator can return Uint8Array with encoding "hex", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'hex', false, true, false, execa);
test('Generator can return final string with default encoding', testGeneratorReturnType, foobarString, 'utf8', true, false, true, execa);
test('Generator can return final Uint8Array with default encoding', testGeneratorReturnType, foobarUint8Array, 'utf8', true, false, true, execa);
test('Generator can return final string with encoding "utf16le"', testGeneratorReturnType, foobarString, 'utf16le', true, false, true, execa);
test('Generator can return final Uint8Array with encoding "utf16le"', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, false, true, execa);
test('Generator can return final string with encoding "buffer"', testGeneratorReturnType, foobarString, 'buffer', true, false, true, execa);
test('Generator can return final Uint8Array with encoding "buffer"', testGeneratorReturnType, foobarUint8Array, 'buffer', true, false, true, execa);
test('Generator can return final string with encoding "hex"', testGeneratorReturnType, foobarString, 'hex', true, false, true, execa);
test('Generator can return final Uint8Array with encoding "hex"', testGeneratorReturnType, foobarUint8Array, 'hex', true, false, true, execa);
test('Generator can return final string with default encoding, failure', testGeneratorReturnType, foobarString, 'utf8', false, false, true, execa);
test('Generator can return final Uint8Array with default encoding, failure', testGeneratorReturnType, foobarUint8Array, 'utf8', false, false, true, execa);
test('Generator can return final string with encoding "utf16le", failure', testGeneratorReturnType, foobarString, 'utf16le', false, false, true, execa);
test('Generator can return final Uint8Array with encoding "utf16le", failure', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, false, true, execa);
test('Generator can return final string with encoding "buffer", failure', testGeneratorReturnType, foobarString, 'buffer', false, false, true, execa);
test('Generator can return final Uint8Array with encoding "buffer", failure', testGeneratorReturnType, foobarUint8Array, 'buffer', false, false, true, execa);
test('Generator can return final string with encoding "hex", failure', testGeneratorReturnType, foobarString, 'hex', false, false, true, execa);
test('Generator can return final Uint8Array with encoding "hex", failure', testGeneratorReturnType, foobarUint8Array, 'hex', false, false, true, execa);
test('Generator can return final string with default encoding, objectMode', testGeneratorReturnType, foobarString, 'utf8', true, true, true, execa);
test('Generator can return final Uint8Array with default encoding, objectMode', testGeneratorReturnType, foobarUint8Array, 'utf8', true, true, true, execa);
test('Generator can return final string with encoding "utf16le", objectMode', testGeneratorReturnType, foobarString, 'utf16le', true, true, true, execa);
test('Generator can return final Uint8Array with encoding "utf16le", objectMode', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, true, true, execa);
test('Generator can return final string with encoding "buffer", objectMode', testGeneratorReturnType, foobarString, 'buffer', true, true, true, execa);
test('Generator can return final Uint8Array with encoding "buffer", objectMode', testGeneratorReturnType, foobarUint8Array, 'buffer', true, true, true, execa);
test('Generator can return final string with encoding "hex", objectMode', testGeneratorReturnType, foobarString, 'hex', true, true, true, execa);
test('Generator can return final Uint8Array with encoding "hex", objectMode', testGeneratorReturnType, foobarUint8Array, 'hex', true, true, true, execa);
test('Generator can return final string with default encoding, objectMode, failure', testGeneratorReturnType, foobarString, 'utf8', false, true, true, execa);
test('Generator can return final Uint8Array with default encoding, objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'utf8', false, true, true, execa);
test('Generator can return final string with encoding "utf16le", objectMode, failure', testGeneratorReturnType, foobarString, 'utf16le', false, true, true, execa);
test('Generator can return final Uint8Array with encoding "utf16le", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, true, true, execa);
test('Generator can return final string with encoding "buffer", objectMode, failure', testGeneratorReturnType, foobarString, 'buffer', false, true, true, execa);
test('Generator can return final Uint8Array with encoding "buffer", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'buffer', false, true, true, execa);
test('Generator can return final string with encoding "hex", objectMode, failure', testGeneratorReturnType, foobarString, 'hex', false, true, true, execa);
test('Generator can return final Uint8Array with encoding "hex", objectMode, failure', testGeneratorReturnType, foobarUint8Array, 'hex', false, true, true, execa);
test('Generator can return string with default encoding, sync', testGeneratorReturnType, foobarString, 'utf8', true, false, false, execaSync);
test('Generator can return Uint8Array with default encoding, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', true, false, false, execaSync);
test('Generator can return Buffer with default encoding, sync', testGeneratorReturnType, foobarBuffer, 'utf8', true, false, false, execaSync);
test('Generator can return string with encoding "utf16le", sync', testGeneratorReturnType, foobarString, 'utf16le', true, false, false, execaSync);
test('Generator can return Uint8Array with encoding "utf16le", sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, false, false, execaSync);
test('Generator can return Buffer with encoding "utf16le", sync', testGeneratorReturnType, foobarBuffer, 'utf16le', true, false, false, execaSync);
test('Generator can return string with encoding "buffer", sync', testGeneratorReturnType, foobarString, 'buffer', true, false, false, execaSync);
test('Generator can return Uint8Array with encoding "buffer", sync', testGeneratorReturnType, foobarUint8Array, 'buffer', true, false, false, execaSync);
test('Generator can return Buffer with encoding "buffer", sync', testGeneratorReturnType, foobarBuffer, 'buffer', true, false, false, execaSync);
test('Generator can return string with encoding "hex", sync', testGeneratorReturnType, foobarString, 'hex', true, false, false, execaSync);
test('Generator can return Uint8Array with encoding "hex", sync', testGeneratorReturnType, foobarUint8Array, 'hex', true, false, false, execaSync);
test('Generator can return Buffer with encoding "hex", sync', testGeneratorReturnType, foobarBuffer, 'hex', true, false, false, execaSync);
test('Generator can return string with default encoding, failure, sync', testGeneratorReturnType, foobarString, 'utf8', false, false, false, execaSync);
test('Generator can return Uint8Array with default encoding, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', false, false, false, execaSync);
test('Generator can return string with encoding "utf16le", failure, sync', testGeneratorReturnType, foobarString, 'utf16le', false, false, false, execaSync);
test('Generator can return Uint8Array with encoding "utf16le", failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, false, false, execaSync);
test('Generator can return string with encoding "buffer", failure, sync', testGeneratorReturnType, foobarString, 'buffer', false, false, false, execaSync);
test('Generator can return Uint8Array with encoding "buffer", failure, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', false, false, false, execaSync);
test('Generator can return string with encoding "hex", failure, sync', testGeneratorReturnType, foobarString, 'hex', false, false, false, execaSync);
test('Generator can return Uint8Array with encoding "hex", failure, sync', testGeneratorReturnType, foobarUint8Array, 'hex', false, false, false, execaSync);
test('Generator can return string with default encoding, objectMode, sync', testGeneratorReturnType, foobarString, 'utf8', true, true, false, execaSync);
test('Generator can return Uint8Array with default encoding, objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', true, true, false, execaSync);
test('Generator can return string with encoding "utf16le", objectMode, sync', testGeneratorReturnType, foobarString, 'utf16le', true, true, false, execaSync);
test('Generator can return Uint8Array with encoding "utf16le", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, true, false, execaSync);
test('Generator can return string with encoding "buffer", objectMode, sync', testGeneratorReturnType, foobarString, 'buffer', true, true, false, execaSync);
test('Generator can return Uint8Array with encoding "buffer", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', true, true, false, execaSync);
test('Generator can return string with encoding "hex", objectMode, sync', testGeneratorReturnType, foobarString, 'hex', true, true, false, execaSync);
test('Generator can return Uint8Array with encoding "hex", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'hex', true, true, false, execaSync);
test('Generator can return string with default encoding, objectMode, failure, sync', testGeneratorReturnType, foobarString, 'utf8', false, true, false, execaSync);
test('Generator can return Uint8Array with default encoding, objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', false, true, false, execaSync);
test('Generator can return string with encoding "utf16le", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'utf16le', false, true, false, execaSync);
test('Generator can return Uint8Array with encoding "utf16le", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, true, false, execaSync);
test('Generator can return string with encoding "buffer", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'buffer', false, true, false, execaSync);
test('Generator can return Uint8Array with encoding "buffer", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', false, true, false, execaSync);
test('Generator can return string with encoding "hex", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'hex', false, true, false, execaSync);
test('Generator can return Uint8Array with encoding "hex", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'hex', false, true, false, execaSync);
test('Generator can return final string with default encoding, sync', testGeneratorReturnType, foobarString, 'utf8', true, false, true, execaSync);
test('Generator can return final Uint8Array with default encoding, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', true, false, true, execaSync);
test('Generator can return final string with encoding "utf16le", sync', testGeneratorReturnType, foobarString, 'utf16le', true, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "utf16le", sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, false, true, execaSync);
test('Generator can return final string with encoding "buffer", sync', testGeneratorReturnType, foobarString, 'buffer', true, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "buffer", sync', testGeneratorReturnType, foobarUint8Array, 'buffer', true, false, true, execaSync);
test('Generator can return final string with encoding "hex", sync', testGeneratorReturnType, foobarString, 'hex', true, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "hex", sync', testGeneratorReturnType, foobarUint8Array, 'hex', true, false, true, execaSync);
test('Generator can return final string with default encoding, failure, sync', testGeneratorReturnType, foobarString, 'utf8', false, false, true, execaSync);
test('Generator can return final Uint8Array with default encoding, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', false, false, true, execaSync);
test('Generator can return final string with encoding "utf16le", failure, sync', testGeneratorReturnType, foobarString, 'utf16le', false, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "utf16le", failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, false, true, execaSync);
test('Generator can return final string with encoding "buffer", failure, sync', testGeneratorReturnType, foobarString, 'buffer', false, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "buffer", failure, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', false, false, true, execaSync);
test('Generator can return final string with encoding "hex", failure, sync', testGeneratorReturnType, foobarString, 'hex', false, false, true, execaSync);
test('Generator can return final Uint8Array with encoding "hex", failure, sync', testGeneratorReturnType, foobarUint8Array, 'hex', false, false, true, execaSync);
test('Generator can return final string with default encoding, objectMode, sync', testGeneratorReturnType, foobarString, 'utf8', true, true, true, execaSync);
test('Generator can return final Uint8Array with default encoding, objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', true, true, true, execaSync);
test('Generator can return final string with encoding "utf16le", objectMode, sync', testGeneratorReturnType, foobarString, 'utf16le', true, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "utf16le", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', true, true, true, execaSync);
test('Generator can return final string with encoding "buffer", objectMode, sync', testGeneratorReturnType, foobarString, 'buffer', true, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "buffer", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', true, true, true, execaSync);
test('Generator can return final string with encoding "hex", objectMode, sync', testGeneratorReturnType, foobarString, 'hex', true, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "hex", objectMode, sync', testGeneratorReturnType, foobarUint8Array, 'hex', true, true, true, execaSync);
test('Generator can return final string with default encoding, objectMode, failure, sync', testGeneratorReturnType, foobarString, 'utf8', false, true, true, execaSync);
test('Generator can return final Uint8Array with default encoding, objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf8', false, true, true, execaSync);
test('Generator can return final string with encoding "utf16le", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'utf16le', false, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "utf16le", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'utf16le', false, true, true, execaSync);
test('Generator can return final string with encoding "buffer", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'buffer', false, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "buffer", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'buffer', false, true, true, execaSync);
test('Generator can return final string with encoding "hex", objectMode, failure, sync', testGeneratorReturnType, foobarString, 'hex', false, true, true, execaSync);
test('Generator can return final Uint8Array with encoding "hex", objectMode, failure, sync', testGeneratorReturnType, foobarUint8Array, 'hex', false, true, true, execaSync);
