const { MongoClient } = require('mongodb');
const chalk = require('chalk');
const path = require('path');
const fs = require('mz/fs');

const homedir = require('os').homedir();

const run = require('./run');

async function pureExport({
    host = 'localhost',
    port = '27017',
    db,
    repo,
    branch = 'master',
    tmpDir = `${__dirname}/__tmp`,
    gitUserName,
    gitUserEmail
}) {
    const now = new Date();

    console.log(chalk.yellow('Starting mongodb export'));

    const collectionNames = await new Promise((resolve, reject) => {
        MongoClient.connect(`mongodb://${host}:${port}/${db}`, (err, connection) => {
            connection.listCollections().toArray((err, items) => { // eslint-disable-line no-shadow
                if (err) {
                    console.log(chalk.red(err));
                    reject(err);
                } else {
                    resolve(items.map(({ name }) => name));
                }
            });

            connection.close();
        });
    });

    console.log(chalk.cyan('Cleaning up'));

    await run(`rm -rf ${tmpDir}`);

    console.log(chalk.cyan('Cloning backup repository'));

    try {
        // Travis CI and maybe other environments require this step
        await run(`eval \`ssh-agent -s\` &&
        ssh-add ~/.ssh/id_rsa`);
    } catch (e) {} // eslint-disable-line no-empty

    console.log(await run(`
        git clone -b ${branch} ${repo} ${tmpDir} &&
        cd ${tmpDir}
    `));

    for (const collection of collectionNames) {
        if (collection === 'sessions') {
            return;
        }

        console.log(chalk.cyan(`Exporting ${collection}`));
        console.log(await run(`mongoexport --db ${db} --collection ${collection} --out ${tmpDir}/${collection}.json`));
    }

    console.log(chalk.cyan(`Committing ${now}`));

    console.log(await run(`
        cd ${tmpDir} &&
        ${gitUserEmail ? `git config user.email "${gitUserEmail}" &&` : ''}
        ${gitUserName ? `git config user.name "${gitUserName}" &&` : ''}
        git add --all &&
        git commit -m "Automatic mongoexport via mongo-git-backup - ${now}" ||
        echo 'Cannot commit. Looks like there are no changes at DB.'
    `));

    console.log(chalk.cyan('Pushing'));

    console.log(await run(`
        cd ${tmpDir} &&
        git push origin ${branch}
    `));

    console.log(chalk.cyan('Cleaning up'));

    await run(`rm -rf ${tmpDir}`);

    console.log(chalk.green('Done!'));
}

async function daemonizeExport(options) {
    const { repo, branch = 'master' } = options;
    const instancesPath = path.resolve(homedir, '.pm2/.mongo-git-backup-instances.json');
    const instances = await fs.exists(instancesPath)
        ? JSON.parse(await fs.readFile(instancesPath)) : {};

    console.log(chalk.cyan('Daemonizing'));

    instances[`${repo}#${branch}`] = options;

    await fs.writeFile(instancesPath, JSON.stringify(instances, null, '\t'));

    console.log(await run(`
        pm2 start ${__dirname}/daemon.js --name="mongo-git-backup" --error="${__dirname}/err.log" --log="${__dirname}/out.log"
    `));

    console.log(chalk.green('Done!'));

    return undefined;
}

async function undaemonizeExport(options) {
    const { repo, branch = 'master' } = options;
    const instancesPath = path.resolve(__dirname, '../.instances.json');
    const instances = await fs.exists(instancesPath)
        ? JSON.parse(await fs.readFile(instancesPath)) : {};

    console.log(chalk.cyan('UnDaemonizing'));

    delete instances[`${repo}#${branch}`];

    await fs.writeFile(instancesPath, JSON.stringify(instances, null, '\t'));

    console.log(await run('pm2 delete mongo-git-backup'));

    console.log(chalk.green('Done!'));

    return undefined;
}

function exportToGit(options) {
    const { daemonize, undaemonize } = options;
    if (undaemonize) {
        return undaemonizeExport(options);
    }

    if (daemonize) {
        return daemonizeExport(options);
    }

    return pureExport(options);
}

module.exports = exportToGit;

module.exports.pureExport = pureExport;

@@ -127,16 +127,63 @@
 mz/fs');
+%0Aconst %7B spawn %7D = require('mz/child_process');
 %0A%0Aconst 
@@ -2642,31 +2642,20 @@
 h = 
-path.resolve(
+%60$%7B
 homedir
-, '
+%7D/
 .pm2
@@ -2679,34 +2679,33 @@
 p-instances.json
-')
+%60
 ;%0A    const inst
@@ -3003,25 +3003,16 @@
 it run(%60
-%0A        
 pm2 star
@@ -3077,56 +3077,100 @@
 =%22$%7B
-__dirname%7D/err.log%22 --log=%22$%7B__dirname%7D/
+homedir%7D/.pm2/.mongo-git-backup-error.log%22 --log=%22$%7Bhomedir%7D/.pm2/.mongo-git-backup-
 out.log%22
 %0A   
@@ -3165,21 +3165,16 @@
 out.log%22
-%0A    
 %60));%0A%0A  

Store logs at .pm2 folder