/* eslint no-console: 0 */

/**
 * These utils are made to simplify more complex fs operations for the node scripts.
 *
 * @author boda@redhotmagma.de
 */

const fs = require('fs');
const path = require('path');

function mkDirDeep(dst) {
    const ps = dst.split(/[/\\]/);
    let dir = ps.splice(0, 1);
    for (const p of ps) {
        dir = [dir, p].join('/');
        if (!fs.existsSync(dir)) {
            console.log('Create directory:', dir);
            fs.mkdirSync(dir);
        }
    }
}

function walkDir(dir, cb, cbAfter) {
    const files = fs.readdirSync(dir);
    for (const f of files) {
        const cf = dir + '/' + f;
        const s = fs.lstatSync(cf);
        cb && cb(cf);
        s.isDirectory() && walkDir(cf, cb, cbAfter);
        cbAfter && cbAfter(cf);
    }
}

function cpDirDeep(src, dst, testFn) {
    mkDirDeep(dst);

    walkDir(src, function(file) {
        const relativePath = file.replace(src, '');
        const tp = path.resolve(dst + relativePath);
        if (testFn && !testFn(file, tp)) {
            return;
        }
        if (fs.statSync(file).isFile()) {
            console.log('Copy file: ' + file + ' -> ' + tp);
            fs.createReadStream(file).pipe(fs.createWriteStream(tp));
        } else if (!fs.existsSync(tp)) {
            try {
                fs.mkdirSync(tp);
            } catch (e) {
                console.log('Could not create directory:', tp);
                console.log(e.message)
            }
        }
    });
}

const testMatchers = {
    keepIfExists: matcher => (src, dst) => {
        if (!(matcher instanceof RegExp)) {
            throw new Error('matcher must be a RegExp!');
        }
        const result = !matcher.test(dst) || !fs.existsSync(dst);
        !result && console.log('Keep existing file: ' + dst + ' > keepIfExists: ' + matcher);
        return result;
    },
};

module.exports = {
    mkDirDeep,
    walkDir,
    cpDirDeep,
    testMatchers,
};
