import { writeFile } from 'fs/promises'

import { buildEslintConfig, buildTsConfig } from '../config.js'
import { ensureIgnore, getPathFromCwd, readInternalFile } from '../utils.js'

/**
 * Generates basic project tooling config files and adds the paths to a
 * .gitignore file.
 */
export async function configure() {
	let gitIgnorePatterns = []

	/** @todo Detect if project is a module and change name to .cjs. */
	let eslintConfigFile = '.eslintrc.js'
	await writeFileToCwd(eslintConfigFile, buildEslintConfig())
	gitIgnorePatterns.push(eslintConfigFile)

	let prettierConfigFile = 'prettier.config.js'
	let prettierConfig = await readInternalFile('../config/prettier.cjs')
	await writeFileToCwd(prettierConfigFile, prettierConfig)
	gitIgnorePatterns.push(prettierConfigFile)

	let tsConfigFile = 'tsconfig.json'
	await writeFileToCwd(tsConfigFile, buildTsConfig(), { json: true })
	gitIgnorePatterns.push(tsConfigFile)

	await ensureIgnore({
		filepath: getPathFromCwd('.gitignore'),
		patterns: gitIgnorePatterns.map((p) => convertPaths(p)),
		comment: 'CONFIGURED BY ZAZEN',
	})
}

/**
 * Convert path slashes to forward slashes.
 *
 * @param {string} path
 */
function convertPaths(path) {
	return path.replace(/\\/g, '/')
}

/**
 * Adds a banner comment to a string, separated by a newline.
 * @param {string} string
 */
export function prependBanner(string) {
	return `/** THIS FILE IS GENERATED BY ZAZEN, MANUAL CHANGES WILL BE DISCARDED. **/\n${string}`
}

/**
 * Write a file to the current process working directory.
 *
 * @param {string} fileName
 * @param {string | unknown} content
 * @param {{ banner?: boolean, json?: boolean }} options [{ banner = true, json = false }={}]
 */
async function writeFileToCwd(
	fileName,
	content,
	{ banner = true, json = false } = {}
) {
	let outPath = getPathFromCwd(fileName)
	let string = json ? JSON.stringify(content, null, 2) : content
	let contentString = banner ? prependBanner(string) : string

	await writeFile(outPath, contentString)
}
