'use strict';

const has = require('has');

function collectPoolStatus(stats, { type, host, pool }) {
    const poolStats = [
        ['_allConnections', 'open'],
        ['_freeConnections', 'sleeping'],
        ['_acquiringConnections', 'waiting']
    ]
        .filter(([mysqljsProp]) => has(pool, mysqljsProp) && Array.isArray(pool[mysqljsProp]))
        .reduce(
            (stats, [mysqljsProp, floraProp]) => ({
                ...stats,
                [floraProp]: pool[mysqljsProp].length
            }),
            {}
        );

    poolStats.open -= poolStats.sleeping;

    return { ...stats, [type]: { [host]: poolStats } };
}

// a cluster contains master/slave pools
function collectClusterStatus(stats, [database, poolCluster]) {
    return {
        ...stats,
        [database]: Object.entries(poolCluster._nodes)
            .map(([identifier, { pool }]) => {
                const [type, host] = identifier.split('_');
                return { type: type.toLowerCase(), host, pool };
            })
            .reduce(collectPoolStatus, {})
    };
}

module.exports = (pools) =>
    Object.entries(pools).reduce(
        (stats, [server, databases]) => ({
            ...stats,
            [server]: Object.entries(databases)
                .filter(([, poolCluster]) => has(poolCluster, '_nodes') && typeof poolCluster._nodes === 'object')
                .reduce(collectClusterStatus, {})
        }),
        {}
    );

'use strict';

const has = require('has');

function collectPoolStatus(stats, { type, host, pool }) {
    const poolStats = [
        ['_allConnections', 'open'],
        ['_freeConnections', 'sleeping'],
        ['_acquiringConnections', 'waiting']
    ]
        .filter(([mysqljsProp]) => has(pool, mysqljsProp) && Array.isArray(pool[mysqljsProp]))
        .reduce(
            (stats, [mysqljsProp, floraProp]) => ({
                ...stats,
                [floraProp]: pool[mysqljsProp].length
            }),
            {}
        );

    poolStats.open -= poolStats.sleeping;

    return { ...stats, [type]: { [host]: poolStats } };
}

// a cluster contains master/slave pools
function collectClusterStatus(stats, [database, poolCluster]) {
    return {
        ...stats,
        [database]: Object.entries(poolCluster._nodes)
            .map(([identifier, { pool }]) => {
                const [type, host] = identifier.split('_');
                return { type: `${type.toLowerCase()}s`, host, pool };
            })
            .reduce(collectPoolStatus, {})
    };
}

module.exports = (pools) =>
    Object.entries(pools).reduce(
        (stats, [server, databases]) => ({
            ...stats,
            [server]: Object.entries(databases)
                .filter(([, poolCluster]) => has(poolCluster, '_nodes') && typeof poolCluster._nodes === 'object')
                .reduce(collectClusterStatus, {})
        }),
        {}
    );

Rename master -> masters and slave -> slaves in server status