#!/usr/bin/env node
import * as fs from 'fs';
import * as path from 'path';
import { ServerProperties } from '../lib';

class Extress {
	private static Init: string = 'init';

	private static args: string[] = process.argv.slice(2);
	private static command: string | undefined = Extress.args[0];
	private static cwd: string = process.cwd();
	private static configPath: string = path.join(Extress.cwd, 'config.json');
	private static srcPath: string = path.join(Extress.cwd, 'src');
	private static middlewaresPath: string = path.join(Extress.srcPath, 'middlewares');
	private static routesPath: string = path.join(Extress.srcPath, 'routes');

	private static exitWithError(message: string): never {
		return console.error(message), process.exit(1);
	}

	private static loadConfig(): ServerProperties {
		if(!fs.existsSync(Extress.configPath))
			Extress.exitWithError('config.json not found in current directory');

		try {
			const content: string = fs.readFileSync(Extress.configPath, 'utf-8');
			return JSON.parse(content) as ServerProperties;
		} catch (error) {
			const message = error instanceof Error ? error.message : String(error);
			Extress.exitWithError(`Failed to read config.json: ${message}`);
		}
	}

	private static getDefaultConfig(): ServerProperties {
		return {
			port: 3000,
			middlewaresPath: './src/middlewares',
			routesPath: './src/routes',
			json: false,
			urlencoded: false,
			sessions: false
		};
	}

	private static init(): void {
		if(fs.existsSync(Extress.configPath))
			return console.log('config.json already exists');

		const serverCode =
			'import { Server as ExtressServer } from \'extress\';\n\n' +
			'class Server {\n' +
			'\tpublic static async start(): Promise<ExtressServer> {\n' +
			'\t\treturn new ExtressServer().init().then((server: Server) => {\n' +
			'\t\t\treturn server.start(), server;\n' +
			'\t\t});\n' +
			'\t}\n' +
			'}\n\n' +
			'export default Server;';
		
		const indexCode =
			'import Server from \'./Server\';\n\n' +
			'Server.start();';
		
		const exampleMiddleware =
			'import { Middleware, NextFunction, Request, Response } from \'extress\';\n\n' +
			'class DefaultMiddleware extends Middleware {\n' +
			'\tprotected action = (req: Request, res: Response, next: NextFunction) => {\n' +
			'\t\tnext();\n' +
			'\t};\n' +
			'\tprotected order: number = 0;\n' +
			'\tprotected route: string | null = null;\n' +
			'}\n\n' +
			'export default DefaultMiddleware;';
		
		const exampleRoute =
			'import { Route, Request, Response, HttpMethod } from \'extress\';\n\n' +
			'class GetIndex extends Route {\n' +
			'\tprotected action = (req: Request, res: Response) => {\n' +
			'\t\tres.status(200).send(\'Welcome to Extress!\');\n' +
			'\t};\n' +
			'\tprotected route: string | null = \'/\';\n' +
			'\tprotected method: HttpMethod = HttpMethod.GET;\n' +
			'}\n\n' +
			'export default GetIndex;';

		fs.mkdirSync(Extress.srcPath);
		fs.mkdirSync(Extress.middlewaresPath);
		fs.mkdirSync(Extress.routesPath);

		fs.writeFileSync(path.join(Extress.middlewaresPath, 'DefaultMiddleware.ts'), exampleMiddleware);
		fs.writeFileSync(path.join(Extress.routesPath, 'GetIndex.ts'), exampleRoute);
		fs.writeFileSync(path.join(Extress.srcPath, 'Server.ts'), serverCode);
		fs.writeFileSync(path.join(Extress.srcPath, 'index.ts'), indexCode);

		fs.writeFileSync(Extress.configPath, JSON.stringify(Extress.getDefaultConfig(), null, 2), 'utf-8');
		console.log('Project initialized successfully.');
	}

	private static printUsage(): void {
		console.log('Usage:\nextress init');
	}

	public static run(): void {
		switch (Extress.command) {
		case Extress.Init: return Extress.init();
		default: return Extress.printUsage();
		}
	}
}

Extress.run();