"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAll = exports.get = exports.remove = exports.update = exports.create = void 0;
const lodash_1 = __importDefault(require("lodash"));
const deep_extend_1 = __importDefault(require("deep-extend"));
const constraints_1 = __importDefault(require("../validation/constraints"));
const errorTypes_1 = __importDefault(require("../utils/errorTypes"));
const MonitoringService = __importStar(require("../services/monitoringService"));
const NodeService = __importStar(require("../services/nodeService"));
const strings_1 = require("../utils/strings");
const validator_1 = require("../validation/validator");
const Resources = __importStar(require("../utils/resources"));
const nodeFields = ['hostname', 'key', 'email', 'nickname', 'mac', 'coords', 'monitoring'];
function getNormalizedNodeData(reqData) {
    const node = {};
    lodash_1.default.each(nodeFields, function (field) {
        let value = strings_1.normalizeString(reqData[field]);
        if (field === 'mac') {
            value = strings_1.normalizeMac(value);
        }
        node[field] = value;
    });
    return node;
}
const isValidNode = validator_1.forConstraints(constraints_1.default.node, false);
const isValidToken = validator_1.forConstraint(constraints_1.default.token, false);
function create(req, res) {
    const data = Resources.getData(req);
    const node = getNormalizedNodeData(data);
    if (!isValidNode(node)) {
        return Resources.error(res, { data: 'Invalid node data.', type: errorTypes_1.default.badRequest });
    }
    NodeService.createNode(node)
        .then(result => Resources.success(res, result))
        .catch(err => Resources.error(res, err));
}
exports.create = create;
function update(req, res) {
    const data = Resources.getData(req);
    const token = strings_1.normalizeString(data.token);
    if (!isValidToken(token)) {
        return Resources.error(res, { data: 'Invalid token.', type: errorTypes_1.default.badRequest });
    }
    const node = getNormalizedNodeData(data);
    if (!isValidNode(node)) {
        return Resources.error(res, { data: 'Invalid node data.', type: errorTypes_1.default.badRequest });
    }
    NodeService.updateNode(token, node)
        .then(result => Resources.success(res, result))
        .catch(err => Resources.error(res, err));
}
exports.update = update;
function remove(req, res) {
    const data = Resources.getData(req);
    const token = strings_1.normalizeString(data.token);
    if (!isValidToken(token)) {
        return Resources.error(res, { data: 'Invalid token.', type: errorTypes_1.default.badRequest });
    }
    NodeService.deleteNode(token)
        .then(() => Resources.success(res, {}))
        .catch(err => Resources.error(res, err));
}
exports.remove = remove;
function get(req, res) {
    const token = strings_1.normalizeString(Resources.getData(req).token);
    if (!isValidToken(token)) {
        return Resources.error(res, { data: 'Invalid token.', type: errorTypes_1.default.badRequest });
    }
    NodeService.getNodeDataByToken(token)
        .then(node => Resources.success(res, node))
        .catch(err => Resources.error(res, err));
}
exports.get = get;
async function doGetAll(req) {
    const restParams = await Resources.getValidRestParams('list', 'node', req);
    const nodes = await NodeService.getAllNodes();
    const realNodes = lodash_1.default.filter(nodes, node => 
    // We ignore nodes without tokens as those are only manually added ones like gateways.
    !!node.token);
    const macs = lodash_1.default.map(realNodes, (node) => node.mac);
    const nodeStateByMac = await MonitoringService.getByMacs(macs);
    const enhancedNodes = lodash_1.default.map(realNodes, (node) => {
        const nodeState = nodeStateByMac[node.mac];
        if (nodeState) {
            return deep_extend_1.default({}, node, {
                site: nodeState.site,
                domain: nodeState.domain,
                onlineState: nodeState.state
            });
        }
        return node;
    });
    const filteredNodes = Resources.filter(enhancedNodes, [
        'hostname',
        'nickname',
        'email',
        'token',
        'mac',
        'site',
        'domain',
        'key',
        'onlineState'
    ], restParams);
    const total = filteredNodes.length;
    const sortedNodes = Resources.sort(filteredNodes, [
        'hostname',
        'nickname',
        'email',
        'token',
        'mac',
        'key',
        'site',
        'domain',
        'coords',
        'onlineState',
        'monitoringState'
    ], restParams);
    const pageNodes = Resources.getPageEntities(sortedNodes, restParams);
    return { total, pageNodes };
}
function getAll(req, res) {
    doGetAll(req)
        .then((result) => {
        res.set('X-Total-Count', result.total.toString(10));
        return Resources.success(res, result.pageNodes);
    })
        .catch((err) => Resources.error(res, err));
}
exports.getAll = getAll;
//# sourceMappingURL=nodeResource.js.map