/**
 * Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
 * Node module: @schukai/monster
 *
 * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
 * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
 *
 * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
 * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
 * For more information about purchasing a commercial license, please contact Volker Schukai.
 *
 * SPDX-License-Identifier: AGPL-3.0
 */

export { typeOf };

/**
 * The built-in typeof method is known to have some historical weaknesses.
 * This function tries to provide a better and more accurate result.
 *
 * @param {*} value
 * @return {string}
 * @license AGPLv3
 * @since 1.7.0
 * @copyright Volker Schukai
 * @throws {TypeError} value is not a primitive
 */
function typeOf(value) {
	if (value === null) {
		return "null";
	}

	const baseType = typeof value;

	if (baseType !== "object" && baseType !== "function") {
		return baseType;
	}

	const internalType = {}.toString.call(value).slice(8, -1);

	if (internalType !== "Object") {
		return internalType.toLowerCase();
	}

	const constructorName = value.constructor?.name;
	if (constructorName && constructorName !== "Object") {
		return constructorName.toLowerCase();
	}

	return "object";
}
