'use strict';

var _DataView = require('./_DataView.js');
var _Map = require('./_Map.js');
var _Promise = require('./_Promise.js');
var _Set = require('./_Set.js');
var _WeakMap = require('./_WeakMap.js');
var _baseGetTag = require('./_baseGetTag.js');
var _toSource = require('./_toSource.js');

/** `Object#toString` result references. */
var mapTag = '[object Map]',
    objectTag = '[object Object]',
    promiseTag = '[object Promise]',
    setTag = '[object Set]',
    weakMapTag = '[object WeakMap]';

var dataViewTag = '[object DataView]';

/** Used to detect maps, sets, and weakmaps. */
var dataViewCtorString = _toSource(_DataView),
    mapCtorString = _toSource(_Map),
    promiseCtorString = _toSource(_Promise),
    setCtorString = _toSource(_Set),
    weakMapCtorString = _toSource(_WeakMap);

/**
 * Gets the `toStringTag` of `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
exports.default = _baseGetTag;

// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
if ((_DataView && exports.default(new _DataView(new ArrayBuffer(1))) != dataViewTag) ||
    (_Map && exports.default(new _Map) != mapTag) ||
    (_Promise && exports.default(_Promise.resolve()) != promiseTag) ||
    (_Set && exports.default(new _Set) != setTag) ||
    (_WeakMap && exports.default(new _WeakMap) != weakMapTag)) {
  exports.default = function(value) {
    var result = _baseGetTag(value),
        Ctor = result == objectTag ? value.constructor : undefined,
        ctorString = Ctor ? _toSource(Ctor) : '';

    if (ctorString) {
      switch (ctorString) {
        case dataViewCtorString: return dataViewTag;
        case mapCtorString: return mapTag;
        case promiseCtorString: return promiseTag;
        case setCtorString: return setTag;
        case weakMapCtorString: return weakMapTag;
      }
    }
    return result;
  };
}

module.exports = exports.default;
