/* eslint-disable no-console */
const path = require('path');
const getopts = require('getopts');
const Myt = require('@verdnatura/myt/myt');
const Run = require('@verdnatura/myt/myt-run');
const helper = require('./tests-helper');

const opts = getopts(process.argv.slice(2), {
    string: [
        'network'
    ],
    boolean: [
        'ci',
        'junit'
    ]
});

let server;
const PARALLEL = false;
const SETUP_TIMEOUT = 15 * 60 * 1000;
const SPEC_TIMEOUT = 30 * 1000;

process.on('exit', teardown);
process.on('uncaughtException', onError);
process.on('unhandledRejection', onError);

const exitSignals = [
    'SIGINT',
    'SIGUSR1',
    'SIGUSR2'
];
for (const signal of exitSignals)
    process.on(signal, () => process.exit());

async function setup() {
    console.log('Building and running DB container.');

    const myt = new Myt();
    await myt.init({
        workspace: path.join(__dirname, '..'),
        random: true,
        ci: opts.ci,
        tmpfs: process.platform == 'linux',
        network: opts.network || null
    });
    server = await myt.run(Run);
    await myt.deinit();

    const {dbConfig} = server;
    process.env.DB_HOST = dbConfig.host;
    process.env.DB_PORT = dbConfig.port;

    if (!PARALLEL)
        await helper.init();
}

async function teardown() {
    if (!server) return;
    const oldServer = server;
    server = null;

    if (!PARALLEL)
        await helper.deinit();

    console.log('Stopping and removing DB container.');
    await oldServer.rm();
}

async function onError(err) {
    console.error(err);
    process.exit(1);
}

async function test() {
    let runner;
    const config = {
        globalSetup: setup,
        globalSetupTimeout: SETUP_TIMEOUT,
        globalTeardown: teardown,
        globalTeardownTimeout: SETUP_TIMEOUT,
        spec_dir: '.',
        spec_files: [
            'back/**/*[sS]pec.js',
            'loopback/**/*[sS]pec.js',
            'modules/*/back/**/*.[sS]pec.js'
        ],
        helpers: []
    };

    if (PARALLEL) {
        const ParallelRunner = require('jasmine/parallel');
        runner = new ParallelRunner({numWorkers: 1});
        config.helpers.push(`back/tests-helper.js`);
    } else {
        const Jasmine = require('jasmine');
        runner = new Jasmine();

        const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
        runner.addReporter(new SpecReporter({
            spec: {
                displaySuccessful: opts.ci,
                displayPending: opts.ci
            },
            summary: {
                displayPending: false,
            }
        }));
    }

    if (opts.junit) {
        const JunitReporter = require('jasmine-reporters');
        runner.addReporter(new JunitReporter.JUnitXmlReporter());
    }
    if (opts.ci)
        runner.jasmine.DEFAULT_TIMEOUT_INTERVAL = SPEC_TIMEOUT;

    // runner.loadConfigFile('back/jasmine.json');
    runner.loadConfig(config);
    process.env.SPEC_IS_RUNNING = true;
    await runner.execute();
}

test();