import { describe, test } from 'manten';
import { expectTypeOf } from 'expect-type';
import { getFlag } from '#type-flag';

// Test Helpers
const toDate = (s: string) => new Date(s);
const toCustomObject = (s: string) => ({ value: s });
const toAny = (v: string) => v as any; // eslint-disable-line @typescript-eslint/no-explicit-any
const toUnknown = (v: string) => v as unknown;

describe('Types', () => {
	test('getFlag standard types', () => {
		const string_ = getFlag('--foo', String);
		expectTypeOf(string_).toEqualTypeOf<string | undefined>();

		const number_ = getFlag('--foo', Number);
		expectTypeOf(number_).toEqualTypeOf<number | undefined>();

		const bool = getFlag('--foo', Boolean);
		expectTypeOf(bool).toEqualTypeOf<boolean | undefined>();
	});

	test('getFlag array types', () => {
		const stringArray = getFlag('--foo', [String]);
		expectTypeOf(stringArray).toEqualTypeOf<string[]>();

		const numberArray = getFlag('--foo', [Number]);
		expectTypeOf(numberArray).toEqualTypeOf<number[]>();

		const boolArray = getFlag('--foo', [Boolean]);
		expectTypeOf(boolArray).toEqualTypeOf<boolean[]>();
	});

	test('getFlag custom types', () => {
		const date = getFlag('--foo', toDate);
		expectTypeOf(date).toEqualTypeOf<Date | undefined>();

		const object = getFlag('--foo', toCustomObject);
		expectTypeOf(object).toEqualTypeOf<{ value: string } | undefined>();
	});

	test('getFlag custom array types', () => {
		const dates = getFlag('--foo', [toDate]);
		expectTypeOf(dates).toEqualTypeOf<Date[]>();

		const objs = getFlag('--foo', [toCustomObject]);
		expectTypeOf(objs).toEqualTypeOf<{ value: string }[]>();
	});

	test('getFlag special types', () => {
		const anyFlag = getFlag('--foo', toAny);

		// eslint-disable-next-line @typescript-eslint/no-explicit-any
		expectTypeOf(anyFlag).toEqualTypeOf<any | undefined>();

		const unknownFlag = getFlag('--foo', toUnknown);
		expectTypeOf(unknownFlag).toEqualTypeOf<unknown | undefined>();

		const anyArray = getFlag('--foo', [toAny]);
		// eslint-disable-next-line @typescript-eslint/no-explicit-any
		expectTypeOf(anyArray).toEqualTypeOf<any[]>();

		const unknownArray = getFlag('--foo', [toUnknown]);
		expectTypeOf(unknownArray).toEqualTypeOf<unknown[]>();
	});
});
