const cli = require('../cli-util');
const fs = require('fs');
const path = require('path');
const config = require('./config');

const { app, version } = config;
const packageConfigPath = path.join(process.cwd(), app || '', 'package.json');

if (!fs.existsSync(packageConfigPath)) {
    console.log(
        'The specified directory doesn\'t look like a Node project. ' +
        'No \'package.json\' found on this location.'
    );
}

const packageConfigTab = getPackageConfigTab();

if (!version) {
    return console.log('Please specify the version: -v <version>');
}

cli.cmd('git symbolic-ref --short HEAD').then(output => {
    const currentBranch = (output || '').trim();

    if (!currentBranch) {
        return console.log(`✘ failed to get current branch`);
    }

    console.log(`✔ current branch: ${cli.bold(currentBranch)}`);

    const context = app ? `cd ${app} && ` : '';

    cli.cmd([
        config.apply(config.preversion),
        `${context}sed -i '' -E 's/^(${packageConfigTab}"version": )"[^"]*"/\\1"${version}"/g' package.json`,
        `${context}sed -i '' -E 's/^(${packageConfigTab}"version": )"[^"]*"/\\1"${version}"/g' package-lock.json`,
        `git commit -am "${config.version_tag}"`,
        `git tag "${config.version_tag}"`,
        `git push origin ${currentBranch} --tags --no-verify`,
        config.apply(config.postversion)
    ])
    .then(() => {
        if (app) {
            console.log(`✔ version of ${cli.bold(app)} updated to ${cli.bold(version)} on ${cli.bold(currentBranch)}`);
        }
        else {
            console.log(`✔ version updated to ${cli.bold(version)} on ${cli.bold(currentBranch)}`);
        }

        if (cli.hasArg('--push')) {
            const pushCmd = [ 'node', path.join(__dirname, 'push') ]
                .concat(process.argv.slice(2))
                .filter(arg => arg !== '--push')
                .join(' ');

            console.log();
            cli.cmd(pushCmd, { verbose: true });
        }
    })
    .catch(error => {
        console.log('✘ version update failed');
        console.log(error);
    });
});

function getPackageConfigTab() {
    if (!fs.existsSync(packageConfigPath)) {
        return '';
    }

    const packageConfig = fs.readFileSync(packageConfigPath).toString();
    let tab = null;

    packageConfig.split(/\r?\n/).forEach(line => {
        const lineTab = (line.match(/^\s+/) || [])[0] || '';

        if (lineTab.length && (tab === null || lineTab.length < tab.length)) {
            tab = lineTab;
        }
    });

    return tab || '';
}
