#!/usr/bin/env node

// Imports
const program = require('commander');
const inquirer = require('inquirer');
const file = require('./src/file');
const cst = require('./src/constant');
const timer = require('./src/timer');

// Variables configs et globales
let preprocessFile = './data/data.ppf';
let verbose = false;

// Parametrage CLI
program.version('1.4.2');

program
    .option('-n, --name <string>', 'Nom de l\'auteur dont il faut chercher les co-auteurs')
    .option('-f, --file <source>', 'Chemin vers le fichier à utiliser pour la recherche des co-auteurs', preprocessFile)
    .option('-p, --process <source>', 'Prepare le fichier source et effectue la recherche des co-auteurs')
    .option('-v, --verbose', 'Affiche plus d\'informations', verbose);
program
    .command('prepare <source> [destination]')
    .description(`Prepare un fichier XML (source) pour la recherche des co-auteurs, le resultat est mis dans le fichier destination (default: "${preprocessFile}")`)
    .action((source, destination = preprocessFile) => {
        if (file.exist(source)) {
            verbose = true;
            parse(source, destination, () => {
                process.exit();
            });
        } else {
            console.error(cst.toString(cst.FILE_NOT_FOUND) + ': ' + source);
            process.exit(cst.FILE_NOT_FOUND);
        }
    });

// Parse des arguments CLI
program.parse(process.argv);

// Si on est pas en train de preparer le fichier de pre traitement
if (process.argv[2] !== 'prepare') {
    // Lecture des options
    const name = (program.name && typeof program.name === 'string') ? program.name : null;
    let source = (program.process) ? program.process : program.file;
    verbose = program.verbose;

    // Verification que le fichier du pre-traitement existe
    if (!file.exist(source)) {
        // Impossible de trouver le fichier XML à traiter
        if (program.process) {
            console.error(cst.toString(cst.FILE_NOT_FOUND) + ': ' + source);
            process.exit(cst.FILE_NOT_FOUND);
        }
        // Impossible de trouver le fichier resultant du pre-traitement
        else {
            console.error(cst.toString(cst.PREPROCESS_NOT_FOUND));
            process.exit(cst.PREPROCESS_NOT_FOUND);
        }
    }

    // En cas d'absence de nom on le demande
    if (name === null) {
        inquirer.prompt({
            type: 'input',
            name: 'name',
            message: 'Enter the name of the author whose co-authors you want to search for: >',
        }).then(answer => {
            // Lancement du prgramme
            if (program.process) {
                parse(source, preprocessFile, ppf => {
                    find(ppf, name);
                });
            } else {
                find(source, answer.name);
            }
        });
    }
    // Sinon on lance le programme
    else {
        if (program.process) {
            parse(source, preprocessFile, ppf => {
                find(ppf, name);
            });
        } else {
            find(source, name);
        }
    }
}

/**
 * Prepare le document XML pour la recherche des co-auteurs
 * @param source Chemin vers le fichier XML
 * @param dest Chemin pour créer le fichier avec les données traitées
 * @param callback Fonction à appelet après l'analyse, prend en parametre le chemin vers le fichier .ppf
 */
function parse(source, dest, callback = null) {
    // Verification que l'extension du fichier dest est bien .ppf
    if (file.getExtension(dest) !== 'ppf') {
        dest += '.ppf';
    }
    // Affichage si verbose des infos
    if (verbose) {
        console.info('Beginning of pre-processing...');
        timer.start();
    }
    // Analyse du fichier xml
    const parser = require('./src/coauth/parser').from(source).to(dest);
    parser.parse(dest => {
        if (verbose) {
            timer.stop();
            console.info(`Pre-processing file created at ${dest} in ${timer.time()}`);
        }
        if (callback !== null) {
            callback(dest);
        }
    });
}

/**
 * Cherche les co-auteurs d'un auteur dans un fichier crée par prepare
 * @param source Chemin vers le fichier crée par prepare
 * @param name Nom de l'auteur pour la recherche
 */
function find(source, name) {
    name = name.trim();
    if (verbose) {
        console.info(`Search for ${name}'s co-authors...`);
        timer.start();
    }
    const finder = require('./src/coauth/finder');
    finder.in(source).find(name, (result) => {
        if (verbose) {
            timer.stop();
            console.info(`${name}'s co-authors find in ${timer.time()}`);
        }
        console.info(finder.print(result));
    });
}
