"use strict";
/**
 * Copyright © 2018 Emu Analytics
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.expandArrays = exports.getMetadataKeyValues = exports.domainsFromString = exports.domainsToString = exports.extentFromString = exports.extentToString = exports.isValidExtent = exports.isNumeric = exports.resolveResource = exports.logObject = exports.logDetail = exports.logInfo = exports.logWarning = exports.logError = exports.log = void 0;
const chalk_1 = __importDefault(require("chalk"));
const sync_1 = __importDefault(require("csv-stringify/lib/sync"));
const loose_json_1 = __importDefault(require("loose-json"));
const emoji = __importStar(require("node-emoji"));
const table_1 = require("table");
const stringWidth = require('string-width');
// tslint:disable-next-line:no-console
exports.log = console.log;
function logError(e) {
    if (typeof e === 'string') {
        (0, exports.log)(emoji.emojify(chalk_1.default.bold.red(e)));
    }
    else {
        (0, exports.log)(emoji.emojify(chalk_1.default.bold.red(e.message)));
        if (e.error && e.error.message) {
            logDetail(e.error.message);
        }
    }
}
exports.logError = logError;
function logWarning(s) {
    (0, exports.log)(emoji.emojify(chalk_1.default.bold.yellow(s)));
}
exports.logWarning = logWarning;
function logInfo(s) {
    (0, exports.log)(emoji.emojify(chalk_1.default.bold(s)));
}
exports.logInfo = logInfo;
function logDetail(s) {
    (0, exports.log)(emoji.emojify(chalk_1.default.dim(s)));
}
exports.logDetail = logDetail;
function logObject(o, format = 'table', fields = null) {
    if (!o) {
        return logError('Null object');
    }
    if (format === 'table') {
        let data;
        if (Array.isArray(o)) {
            if (o.length === 0) {
                return (0, exports.log)('No Items');
            }
            if (typeof o[0] === 'object') {
                const keys = fields || Object.keys(o[0]);
                data = [['', ...keys.map(key => chalk_1.default.bold.green(key))]];
                o.forEach((rowObj, index) => {
                    const row = [index.toString(), ...keys.map(key => formatCell(rowObj[key]))];
                    data.push(row);
                });
            }
            else {
                data = [['', chalk_1.default.bold.green('Value')]];
                o.forEach((rowObj, index) => {
                    const row = [index.toString(), formatCell(rowObj)];
                    data.push(row);
                });
            }
        }
        else {
            data = [
                [chalk_1.default.bold.green('Property'), chalk_1.default.bold.green('Value')],
                ...Object.keys(o).map(key => [key, formatCell(o[key])])
            ];
        }
        const maxWidths = maxColumnWidths(data);
        const columnConfig = maxWidths.map(width => ({ width: Math.min(width, 36), truncate: 200 }));
        // tslint:disable-next-line:no-console
        console.log((0, table_1.table)(data, { columns: columnConfig }));
    }
    else if (format === 'csv') {
        if (!Array.isArray(o)) {
            o = [o];
        }
        (0, exports.log)((0, sync_1.default)(o, { header: true }));
    }
    else {
        (0, exports.log)(JSON.stringify(o, null, 2));
    }
}
exports.logObject = logObject;
// Support functions taken from table module
function maxColumnWidths(rows) {
    if (!rows[0]) {
        throw new Error('Dataset must have at least one row.');
    }
    const columns = new Array(rows[0].length).fill(0);
    rows.forEach(row => {
        const columnWidthIndex = cellWidthIndex(row);
        columnWidthIndex.forEach((valueWidth, index0) => {
            if (columns[index0] < valueWidth) {
                columns[index0] = valueWidth;
            }
        });
    });
    return columns;
}
function cellWidthIndex(cells) {
    return cells.map(value => {
        return stringWidth(value);
    });
}
function formatCell(obj) {
    if (Array.isArray(obj)) {
        return '<array>';
    }
    else if (obj === null) {
        return chalk_1.default.grey('null');
    }
    else if (typeof obj === 'undefined') {
        return chalk_1.default.grey('undefined');
    }
    else if (typeof obj === 'object') {
        if ('color' in obj && 'value' in obj) {
            return chalk_1.default.hex(obj.color)(formatCell(obj.value));
        }
        else {
            return '<object>';
        }
    }
    else {
        return obj.toString().replace(/[^ -~]/g, ' ');
    }
}
/**
 * Query client resource endpoint give an ID or unique prefix
 *
 * @param idOrPrefix Resource ID or a unique prefix.
 * @param endpoint Flo.w client endpoint to query
 */
function resolveResource(idOrPrefix, endpoint, idField = 'id', join, sort) {
    return __awaiter(this, void 0, void 0, function* () {
        const results = yield endpoint.list({
            [`filter[${idField}]`]: `~${idOrPrefix}`,
            sort: sort || idField,
            join
        });
        if (results.length === 0) {
            throw new Error('Not found');
        }
        if (results.length > 1 && results[0].id !== idOrPrefix) {
            throw new Error(`Multiple matches for '${idOrPrefix}': ${results.map(d => d[idField]).join(', ')}`);
        }
        return results[0];
    });
}
exports.resolveResource = resolveResource;
function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}
exports.isNumeric = isNumeric;
function isValidExtent(extent) {
    if (!extent || extent.length === 0) {
        return false;
    }
    if (typeof extent === 'string') {
        extent = extent.split(' ');
    }
    if (extent.length !== 4) {
        return false;
    }
    return !extent.find(d => !isNumeric(d));
}
exports.isValidExtent = isValidExtent;
function extentToString(extent) {
    if (!extent || extent.length === 0) {
        return '';
    }
    return extent.map((d) => d.toString()).join(' ');
}
exports.extentToString = extentToString;
function extentFromString(extent) {
    if (extent === null || extent === undefined) {
        return null;
    }
    if (typeof extent === 'string') {
        extent = extent.split(' ');
    }
    return extent.map(d => parseFloat(d));
}
exports.extentFromString = extentFromString;
function domainsToString(domains) {
    if (!Array.isArray(domains) || domains.length === 0) {
        return '';
    }
    return domains.join(', ');
}
exports.domainsToString = domainsToString;
function domainsFromString(domains) {
    if (domains) {
        domains = domains.trim();
    }
    if (!domains) {
        return [];
    }
    return domains.split(',').map(d => d.trim());
}
exports.domainsFromString = domainsFromString;
function getMetadataKeyValues(keyValues) {
    try {
        return keyValues.reduce((accum, param) => {
            const [key, value] = param.split('=');
            try {
                accum[key ? key : null] = (0, loose_json_1.default)(value);
            }
            catch (e) {
                // Set value as string
                accum[key] = value;
            }
            return accum;
        }, {});
    }
    catch (e) {
        throw new Error('Bad format for key/value: specify key/value pairs as <key>=<value>');
    }
}
exports.getMetadataKeyValues = getMetadataKeyValues;
/**
 * Returns a shallow copy of the supplied resource with the specified array-type attributes  converted to
 * comma separated strings for better display in tables.
 *
 * e.g.
 * ```
 * expandArrays(contactPoint, ['templates', 'recipients']);
 * ```
 *
 * @param resource Resource object
 * @param attrs Array-type attributes to expand
 * @returns expanded resource
 */
function expandArrays(resource, attrs) {
    const result = Object.assign({}, resource);
    for (const attr of attrs) {
        if (Array.isArray(result[attr])) {
            result[attr] = result[attr].join(', ');
        }
    }
    return result;
}
exports.expandArrays = expandArrays;
//# sourceMappingURL=index.js.map