#!/usr/bin/env node

// Pollute global scope with Babel polyfills prior to anything else.
// Note: eslint doesn't like unassigned imports.
/* eslint-disable */
require('@babel/polyfill');
/* eslint-enable */

var path = require('path');
var fs = require('fs');
var ini = require('ini');

function help(binaryName) {
    console.log('Usage: ' + binaryName + '\n' +
        '\t-h or --help or help: displays this message.\n' +
        '\t-c $path or --config $path: path to the configuration file.\n' +
        '\t-o $path or --output $path: path to the output file (required).\n'
    );
}

function readConfigFromFile(pathname) {
    var content = null;
    try {
        content = fs.readFileSync(pathname, { encoding: 'utf8' });
    } catch (e) {
        console.error('Error when trying to read the configuration file (does the file at this path exist?)', e.toString(), '\n\n', e.stack);
        process.exit(-1);
    }

    var config = {};
    try {
        config = ini.parse(content);
    } catch (e) {
        console.error('INI formatting error when reading the configuration file:', e.toString(), '\n\n', e.stack);
        process.exit(-1);
    }

    return config;
}

// First two args are [node, binaryname]
var numActualArgs = Math.max(process.argv.length - 2, 0);
function actualArg(n) {
    return process.argv[2 + n];
}

var config = {};
var outputFile = null;
var binaryName = actualArg(-1);
if (numActualArgs >= 1) {
    for (let i = 0; i < numActualArgs; i++) {
        var arg = actualArg(i);
        if (['help', '-h', '--help'].includes(arg)) {
            help(binaryName);
            process.exit(0);
        } else if (['-c', '--config'].includes(arg)) {
            if (numActualArgs < i + 1) {
                console.error('Missing config file path.');
                help(binaryName);
                process.exit(-1);
            }
            var configFilePath = path.resolve(actualArg(i + 1));
            i += 1;
            config = readConfigFromFile(configFilePath);
        } else if (['-o', '--output'].includes(arg)) {
            if (numActualArgs < i + 1) {
                console.error('Missing output file path.');
                help(binaryName);
                process.exit(-1);
            }
            outputFile = path.resolve(actualArg(i + 1));
            i += 1;
        } else {
            console.error('Unknown command:', arg);
            help(binaryName);
            process.exit(-1);
        }
    }
}

if (outputFile === null) {
    console.error('Missing output file.');
    help(binaryName);
    process.exit(-1);
}

// First, define process.kresus.
var root = path.join(path.dirname(fs.realpathSync(__filename)), '..', 'build');

require(path.join(root, 'server', 'config.js')).apply(config);

// Then only, import the server.
var server = require(path.join(root, 'server'));

var dataDir = process.kresus.dataDir;
if (!fs.existsSync(dataDir)) {
    fs.mkdirSync(dataDir);
}

// The server should only create files with +rw permissions for the current
// user.
var processUmask = 0o0077;
process.umask(processUmask);

process.chdir(dataDir);

var defaultDbPath = path.join(dataDir, 'db');

var opts = {
    root: root,
    port: process.kresus.port,
    dbName: defaultDbPath
};

server.main(opts, outputFile)
    .then(() => {
        console.info(`Succesfully exported data to ${outputFile}!`);
    }, err => {
        console.error(`Error when exporting data: ${err.message}
${err.stack}`);
    });
