'use strict';
const _isNil = require('lodash/isNil');
const _isString = require('lodash/isString');
const _isObject= require('lodash/isObject');
/**
* @class
* @description A general-purpose set of utility and helper
* functions for computing what K4 Device Class a given device belongs to.
*/
class DeviceFingerprintUtility {
/**
* @constructor
* @param {Adapter} adapter
*/
constructor(adapter) {
this.adapter = adapter;
}
/**
* @description Based on the supplied identifier field
* names/types to check against, and a fallback default class name, computes
* the appropriate device class.
* @param {String[]} identifierFieldNames A list of accepted field names to
* use from the device mapping fingerprint against which to compare a supplied
* set of input candidate values.
* @param {Object} inputDeviceCandidateValues Key-value pairs of information
* from the device candidate to investigate and compare against the specified
* field names from each device fingerprint in the mappings.
* @param {String} [fallbackClsName] If no device class match is found, use
* this device class.
* @returns {String} Returns the matching device class for the candidate values
* supplied compared against the select fields from the device fingerprint.
* If no class is found, the fallback class string is returned. If that too
* is not specified, an empty string is returned.
*/
calculateDeviceClass(identifierFieldNames, inputDeviceCandidateValues, fallbackClsName) {
const fallbackClassNameToUse = _isString(fallbackClsName) ? fallbackClsName : '';
if (!Array.isArray(identifierFieldNames) ||
identifierFieldNames.length === 0) {
return fallbackClassNameToUse;
}
if (!_isObject(inputDeviceCandidateValues) ||
Object.keys(inputDeviceCandidateValues).length === 0) {
return fallbackClassNameToUse;
}
const mappingDeviceClassesList = Object.keys(this.adapter.mapping);
for (let k = 0; k < mappingDeviceClassesList.length; k += 1) {
const currentDeviceClass = mappingDeviceClassesList[k];
const currentDeviceMapping = this.adapter.mapping[currentDeviceClass];
const currentDeviceFingerprint = currentDeviceMapping.fingerprint;
if (!_isNil(currentDeviceFingerprint) &&
_isObject(currentDeviceFingerprint)) {
const isAMatch = Object.keys(currentDeviceFingerprint)
.filter(fingerprintField => identifierFieldNames.indexOf(fingerprintField) > -1)
.reduce((accumulator, currentFingerprintField) => {
return (
accumulator &&
(currentDeviceFingerprint[currentFingerprintField].indexOf(inputDeviceCandidateValues[currentFingerprintField]) > -1)
);
}, true);
if (isAMatch === true) {
return currentDeviceClass;
}
}
}
return fallbackClassNameToUse;
}
};
module.exports = DeviceFingerprintUtility;