import { readdir } from 'fs';
import { copy, ensureDir, move, pathExists } from 'fs-extra';
import { homedir } from 'os';
import * as path from 'path';
import * as os from 'os';
import * as bnj from 'bonjour';
import { Config, FileHandler } from './FileHandler';
import { WebServer } from './WebServer';
import { SocketServer } from './SocketServer';
import { DeckManager } from './Decks/DeckManager';
import { PageManager } from './Pages/PageManager';
import { IntegrationsManager } from './Integrations/IntegrationsManager';
import { ConnectionManager } from './ConnectionManager';
import { Icons } from './Icons';
import { Log } from './Logger';
const bonjour = bnj();

declare var Undecked: Undecked;
declare var Config: Config;

Undecked = {
	DEVMODE: process.argv.includes('--dev'),

	quality: 96,

	dataPath: path.join(homedir(), 'MorphixProductions', 'Undecked'),

	FileHandler: new FileHandler(),
	WebServer: new WebServer(),
	SocketServer: new SocketServer(),

	Decks: new DeckManager(),
	Pages: new PageManager(),
	Integrations: new IntegrationsManager(),
	Connections: new ConnectionManager(),

	Icons: new Icons(),

	getName() {
		if (Config.name != null) return Config.name;
		if (os.userInfo().username.length > 0) return os.userInfo().username;
		return os.hostname();
	}
};

Undecked.start = () => {
	Log('info', 'Starting Undecked');

	var start = () =>
		Undecked.FileHandler.load(() => {
			Undecked.Decks.load(() => {
				Undecked.Icons.load(() => {
					Undecked.Pages.load(() => {
						Undecked.Integrations.load(() => {
							Undecked.Connections.load(() => {
								Undecked.WebServer.start((server) => {
									Undecked.SocketServer.start(server, () => {
										Log('info', 'Undecked started');

										try {
											bonjour.publish({
												name: Undecked.getName(),
												type: 'undecked',
												port: Config.ports.http
											});
										} catch (error) {}
									});
								});
							});
						});
					});
				});
			});
		});

	pathExists(path.join(homedir(), 'GetiyoSoftware', 'Undecked'), (err, exists) => {
		if (err) throw err;
		if (exists)
			move(path.join(homedir(), 'GetiyoSoftware', 'Undecked'), Undecked.dataPath, (err) => {
				if (err) throw err;
				start();
			});
		else start();
	});
};

Undecked.generateRandom = (
	length: number,
	checksum?: (random: string) => boolean,
	chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
): string => {
	for (let i = 0; i < 1000; i++) {
		let str = '';
		for (let i = 0; i < length; i++) {
			str += chars.charAt(Math.floor(Math.random() * chars.length));
		}

		if (checksum != undefined)
			if (checksum(str)) return str;
			else return str;
	}
};

Undecked.convert = () => {
	var outputWhiteDir = path.join(__filename, '..', '..', '..', 'Static', 'materialicons', 'white');
	var outputBlackDir = path.join(__filename, '..', '..', '..', 'Static', 'materialicons', 'black');

	var inputWhiteDir = path.join(`C:\\Users\\Mees\\Pictures\\materialicons\\white`);
	var inputBlackDir = path.join(`C:\\Users\\Mees\\Pictures\\materialicons\\black`);

	ensureDir(outputWhiteDir, (err) => {
		if (err) throw err;
		ensureDir(inputBlackDir, (err) => {
			if (err) throw err;

			readdir(path.join(inputBlackDir), (err, files) => {
				if (err) throw err;

				console.log(`Found ${files.length} icons`);

				(function handleCopy(i = 0) {
					if (files[i]) {
						var inputWhite = path.join(inputWhiteDir, files[i], 'sharp.png');
						var inputBlack = path.join(inputBlackDir, files[i], 'sharp.png');
						var outputWhite = path.join(outputWhiteDir, `${files[i]}_low.png`);
						var outputBlack = path.join(outputBlackDir, `${files[i]}_low.png`);
						copy(inputWhite, outputWhite, (err) => {
							if (err) console.log(`Error whilst copying white '${files[i]}'`);
							copy(inputBlack, outputBlack, (err) => {
								if (err) console.log(`Error whilst copying black '${files[i]}'`);
								console.log(`Completed convertion on ${i + 1}/${files.length}`);
								handleCopy(i + 1);
							});
						});
					} else console.log('--- Convertion completed ---');
				})();
			});
		});
	});
};

Undecked.start();
export interface Undecked {
	DEVMODE: boolean;

	quality: number;

	dataPath: string;

	FileHandler: FileHandler;
	WebServer: WebServer;
	SocketServer: SocketServer;

	Decks: DeckManager;
	Pages: PageManager;
	Integrations: IntegrationsManager;
	Connections: ConnectionManager;

	Icons: Icons;

	getName: () => string;

	start?: () => void;
	generateRandom?: (length: number, checksum?: (random: string) => boolean, chars?: string) => string;
	convert?: (type: string) => void;
}
