Send log message to all available wrappers

@param {string} id
@param {string} level
@param {boolean} fallbackToLog
@param {[]} rest
function sendMessage(id, level, fallbackToLog, ...rest) {
  const levelMethod = level.toLowerCase();
  const options = buildMessageOptions(id);
  const tagsToDisable = get(configRegistry, 'tags.disable', []);
  const namespaceTags = get(configRegistry, `namespaces.${id}.tags`, []);
  const containsDisabledTag = tagsToDisable.some((element) => {
    return namespaceTags.indexOf(element) > -1;
  });

  if (options.disable.indexOf(level) > -1 ||
    containsDisabledTag) {
    // if global or logger's setting is saying to disable logging, proceed silently
    if (!!configRegistry.verbose) {
      console.log(`Level ${level} or namespace ID ${id} has been disabled. skipping...`);
    }
    return;
  }

  const [, , stats, ...args] = applyPlugins(pluginsRegistry, id, level, calcStats(), ...rest);

  wrappers.concat(options.wrappers)
    .forEach((wrapper) => {
      const restOrArgs = equalsWrapperOptValue(wrapper, 'passInitialArguments', true) ? rest : args;
      const plugins = extractWrapperPlugins(wrapper);
      const [, , wrapperStats, ...wrapperArgs] = applyPlugins(plugins, id, level, stats, ...restOrArgs);

      if (typeof wrapper[levelMethod] === 'function') {
        // use specific logging method if exists, for example, wrapper.info()
        return wrapper[levelMethod](id, wrapperStats, ...wrapperArgs);
      } else if (typeof wrapper.log === 'function' && !!fallbackToLog) {
        // use generic log method, if fallbackToLog === true. It is always equal to TRUE for standard levels
        return wrapper.log(id, level, wrapperStats, ...wrapperArgs);
      }
      if (!!configRegistry.verbose) {
        console.log(`Wrapper has no valid logging method. fallbackToLog is equal ${fallbackToLog}. skipping...`);
      }
    });
}