/*
 * MVKBaseObject.mm
 *
 * Copyright (c) 2015-2021 The Brenwill Workshop Ltd. (http://www.brenwill.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "MVKBaseObject.h"
#include "MVKVulkanAPIObject.h"
#include "MVKInstance.h"
#include "MVKFoundation.h"
#include "MVKOSExtensions.h"
#include <cxxabi.h>

using namespace std;


static const char* getReportingLevelString(int aslLvl) {
	switch (aslLvl) {
		case ASL_LEVEL_DEBUG:
			return "mvk-debug";

		case ASL_LEVEL_INFO:
		case ASL_LEVEL_NOTICE:
			return "mvk-info";

		case ASL_LEVEL_WARNING:
			return "mvk-warn";

		case ASL_LEVEL_ERR:
		case ASL_LEVEL_CRIT:
		case ASL_LEVEL_ALERT:
		case ASL_LEVEL_EMERG:
		default:
			return "mvk-error";
	}
}


#pragma mark -
#pragma mark MVKBaseObject

string MVKBaseObject::getClassName() {
    int status;
    char* demangled = abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status);
    string clzName = demangled;
    free(demangled);
    return clzName;
}

void MVKBaseObject::reportMessage(int aslLvl, const char* format, ...) {
	va_list args;
	va_start(args, format);
	reportMessage(this, aslLvl, format, args);
	va_end(args);
}

void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, ...) {
	va_list args;
	va_start(args, format);
	reportMessage(mvkObj, aslLvl, format, args);
	va_end(args);
}

// This is the core reporting implementation. Other similar functions delegate here.
void MVKBaseObject::reportMessage(MVKBaseObject* mvkObj, int aslLvl, const char* format, va_list args) {

	MVKVulkanAPIObject* mvkAPIObj = mvkObj ? mvkObj->getVulkanAPIObject() : nullptr;
	MVKInstance* mvkInst = mvkAPIObj ? mvkAPIObj->getInstance() : nullptr;
	bool hasDebugCallbacks = mvkInst && mvkInst->hasDebugCallbacks();
	bool shouldLog = (aslLvl < (mvkConfig()->logLevel << 2));

	// Fail fast to avoid further unnecessary processing.
	if ( !(shouldLog || hasDebugCallbacks) ) { return; }

	va_list origArgs, redoArgs;
	va_copy(origArgs, args);
	va_copy(redoArgs, args);

	// Choose a buffer size suitable for most messages and attempt to write it out.
	const int kOrigBuffSize = 2 * KIBI;
	char origBuff[kOrigBuffSize];
	char* pMessage = origBuff;
	int msgLen = vsnprintf(origBuff, kOrigBuffSize, format, origArgs);

	// If message is too big for original buffer, allocate a buffer big enough to hold it and
	// write the message out again. We only want to do this double writing if we have to.
	int redoBuffSize = (msgLen >= kOrigBuffSize) ? msgLen + 1 : 0;
	char *redoBuff = NULL;
	if (redoBuffSize > 0 && (redoBuff = (char *)malloc(redoBuffSize))) {
		pMessage = redoBuff;
		vsnprintf(redoBuff, redoBuffSize, format, redoArgs);
	}

	va_end(redoArgs);
	va_end(origArgs);

	// Log the message to the standard error stream
	if (shouldLog) { fprintf(stderr, "[%s] %s\n", getReportingLevelString(aslLvl), pMessage); }

	// Broadcast the message to any Vulkan debug report callbacks
	if (hasDebugCallbacks) { mvkInst->debugReportMessage(mvkAPIObj, aslLvl, pMessage); }

	free(redoBuff);
}

VkResult MVKBaseObject::reportError(VkResult vkErr, const char* format, ...) {
	va_list args;
	va_start(args, format);
	VkResult rslt = reportError(this, vkErr, format, args);
	va_end(args);
	return rslt;
}

VkResult MVKBaseObject::reportError(MVKBaseObject* mvkObj, VkResult vkErr, const char* format, ...) {
	va_list args;
	va_start(args, format);
	VkResult rslt = reportError(mvkObj, vkErr, format, args);
	va_end(args);
	return rslt;
}

// This is the core reporting implementation. Other similar functions delegate here.
VkResult MVKBaseObject::reportError(MVKBaseObject* mvkObj, VkResult vkErr, const char* format, va_list args) {

	// Prepend the error code to the format string
	const char* vkRsltName = mvkVkResultName(vkErr);
	char fmtStr[strlen(vkRsltName) + strlen(format) + 4];
	sprintf(fmtStr, "%s: %s", vkRsltName, format);

	// Report the error
	va_list lclArgs;
	va_copy(lclArgs, args);
	reportMessage(mvkObj, ASL_LEVEL_ERR, fmtStr, lclArgs);
	va_end(lclArgs);

	return vkErr;
}
