import { readFile, readdir, writeFile, stat } from 'node:fs/promises'
import { resolve, join } from 'node:path'

async function isFile(f: string): Promise<boolean> {
	return (await stat(f)).isFile()
}

async function write(fName: string, str: string): Promise<string> {
	await writeFile(resolve(fName), str)
	return str
}

async function readFolder(folder: string): Promise<string[]> {
	const files = await readdir(resolve(folder))
	return files.map((f) => join(folder, f)).filter(isFile)
}

function read(fName: string): Promise<Buffer> {
	return readFile(resolve(fName))
}

async function concat(files: string[]): Promise<string> {
	return Promise.all(files.map(read)).then((src) => src.join('\n'))
}

export async function concatFiles(folder: string[] | string, outFile?: string): Promise<void> {
	let concatenated: Promise<string>

	if (typeof folder === 'string') {
		const files = await readFolder(folder)
		concatenated = concat(files)
	} else concatenated = concat(folder)

	if (outFile) {
		const output = await concatenated
		await write(outFile, output)
	} else {
		await concatenated
	}
}
