#!/usr/bin/env node
const fs = require('fs-promise');
const path = require('path');
const jsdoc2md = require('jsdoc-to-markdown');
const Documentation = require('./documentation');
const config = require('./config');

const mainPromises = [null, null];

// Parse the JSDocs in all source directories
console.log('Parsing JSDocs in source files...');
const files = [];
for(const dir of config.source) files.push(`${dir}/*.js`, `${dir}/**/*.js`);
mainPromises[0] = jsdoc2md.getTemplateData({ files });

// Load the custom docs
if(config.custom) {
	console.log('Loading custom docs files...');
	const customDir = path.dirname(config.custom);

	// Figure out what type of definitions file we're loading
	let type;
	const defExtension = path.extname(config.custom).toLowerCase();
	if(defExtension === '.json') type = 'json';
	else if(defExtension === '.yml' || defExtension === '.yaml') type = 'yaml';
	else throw new TypeError('Unknown custom docs definition file type.');

	mainPromises[1] = fs.readFile(config.custom, 'utf-8').then(defContent => {
		// Parse the definition file
		let definitions;
		if(type === 'json') definitions = JSON.parse(defContent);
		else definitions = require('js-yaml').safeLoad(defContent);

		const custom = {};
		const filePromises = [];

		for(const category of definitions) {
			// Add the category to the custom docs
			const catID = category.catID || category.path || category.name.toLowerCase();
			const dir = path.join(customDir, category.path || catID);
			custom[catID] = new Array(category.files.length);

			// Add every file in the category
			for(let f = 0; f < category.files.length; f++) {
				const file = category.files[f];
				filePromises.push(fs.readFile(path.join(dir, file.path), 'utf-8').then(content => {
					const extension = path.extname(file.path);
					const fileID = file.id || path.basename(file.path, extension);
					custom[catID][f] = {
						id: fileID,
						name: file.name,
						type: extension.replace(/^\./, ''),
						content
					};
					if(config.verbose) console.log(`Loaded custom docs file ${catID}/${fileID}`);
				}));
			}
		}

		return Promise.all(filePromises).then(() => custom);
	});
}

Promise.all(mainPromises).then(results => {
	const data = results[0];
	const custom = results[1];

	console.log(`${data.length} JSDoc items found.`);
	const fileCount = Object.keys(custom).map(k => custom[k]).reduce((prev, c) => prev + c.length, 0);
	const categoryCount = Object.keys(custom).length;
	console.log(
		`${fileCount} custom doc${fileCount !== 1 ? 's' : ''} files found in ` +
		`${categoryCount} categor${categoryCount !== 1 ? 'ies' : 'y'}.`
	);

	console.log(`Serializing documentation with format version ${Documentation.FORMAT_VERSION}...`);
	const docs = new Documentation(data, custom);
	let output = JSON.stringify(docs.serialize(), null, config.spaces);

	if(config.compress) {
		console.log('Compressing...');
		output = require('zlib').deflateSync(output).toString('utf8');
	}

	if(config.output) {
		console.log(`Writing to ${config.output}...`);
		fs.writeFileSync(config.output, output);
	}

	console.log('Done!');
	process.exit(0);
}).catch(err => {
	console.error(err);
	process.exit(1);
});

@@ -489,16 +489,100 @@
 %7B files 
+%7D).then(data =%3E %7B%0A%09console.log(%60$%7Bdata.length%7D JSDoc items parsed.%60);%0A%09return data;%0A
 %7D);%0A%0A// 
@@ -2234,175 +2234,12 @@
  =%3E 
-custom);%0A%09%7D);%0A%7D%0A%0APromise.all(mainPromises).then(results =%3E %7B%0A%09const data = results%5B0%5D;%0A%09const custom = results%5B1%5D;%0A%0A%09console.log(%60$%7Bdata.length%7D JSDoc items found.%60);%0A
+%7B%0A%09%09
 %09con
@@ -2334,16 +2334,18 @@
 th, 0);%0A
+%09%09
 %09const c
@@ -2387,16 +2387,18 @@
 length;%0A
+%09%09
 %09console
@@ -2403,16 +2403,18 @@
 le.log(%0A
+%09%09
 %09%09%60$%7Bfil
@@ -2480,16 +2480,18 @@
  in %60 +%0A
+%09%09
 %09%09%60$%7Bcat
@@ -2549,17 +2549,149 @@
 'y'%7D.%60%0A%09
-)
+%09%09);%0A%09%09%09return custom;%0A%09%09%7D);%0A%09%7D);%0A%7D%0A%0APromise.all(mainPromises).then(results =%3E %7B%0A%09const data = results%5B0%5D;%0A%09const custom = results%5B1%5D
 ;%0A%0A%09cons

Move some log statements around