/*
 * MVKOSExtensions.mm
 *
 * Copyright (c) 2015-2020 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 "MVKOSExtensions.h"
#include "MVKCommonEnvironment.h"
#include <mach/mach_host.h>
#include <mach/mach_time.h>
#include <mach/task.h>
#include <os/proc.h>

#import <Foundation/Foundation.h>


using namespace std;

static const MVKOSVersion kMVKOSVersionUnknown = 0.0f;
static MVKOSVersion _mvkOSVersion = kMVKOSVersionUnknown;
MVKOSVersion mvkOSVersion() {
    if (_mvkOSVersion == kMVKOSVersionUnknown) {
        NSOperatingSystemVersion osVer = [[NSProcessInfo processInfo] operatingSystemVersion];
        float maj = osVer.majorVersion;
        float min = osVer.minorVersion;
        float pat = osVer.patchVersion;
        _mvkOSVersion = maj + (min / 100.0f) +  + (pat / 10000.0f);
    }
    return _mvkOSVersion;
}

static uint64_t _mvkTimestampBase;
static double _mvkTimestampPeriod;

uint64_t mvkGetTimestamp() { return mach_absolute_time() - _mvkTimestampBase; }

double mvkGetTimestampPeriod() { return _mvkTimestampPeriod; }

double mvkGetElapsedMilliseconds(uint64_t startTimestamp, uint64_t endTimestamp) {
	if (endTimestamp == 0) { endTimestamp = mvkGetTimestamp(); }
	return (double)(endTimestamp - startTimestamp) * _mvkTimestampPeriod / 1e6;
}

// Initialize timestamping capabilities on app startup.
//Called automatically when the framework is loaded and initialized.
static bool _mvkTimestampsInitialized = false;
__attribute__((constructor)) static void MVKInitTimestamps() {
	if (_mvkTimestampsInitialized ) { return; }
	_mvkTimestampsInitialized = true;

	_mvkTimestampBase = mach_absolute_time();
	mach_timebase_info_data_t timebase;
	mach_timebase_info(&timebase);
	_mvkTimestampPeriod = (double)timebase.numer / (double)timebase.denom;
}

void mvkDispatchToMainAndWait(dispatch_block_t block) {
	if (NSThread.isMainThread) {
		block();
	} else {
		dispatch_sync(dispatch_get_main_queue(), block);
	}
}


#pragma mark -
#pragma mark Process environment

string mvkGetEnvVar(string varName, bool* pWasFound) {
	@autoreleasepool {
		NSDictionary* nsEnv = [[NSProcessInfo processInfo] environment];
		NSString* envStr = nsEnv[@(varName.c_str())];
		if (pWasFound) { *pWasFound = envStr != nil; }
		return envStr ? envStr.UTF8String : "";
	}
}

int64_t mvkGetEnvVarInt64(string varName, bool* pWasFound) {
	return strtoll(mvkGetEnvVar(varName, pWasFound).c_str(), NULL, 0);
}

bool mvkGetEnvVarBool(std::string varName, bool* pWasFound) {
	return mvkGetEnvVarInt64(varName, pWasFound) != 0;
}


#pragma mark -
#pragma mark System memory

uint64_t mvkGetSystemMemorySize() {
	mach_msg_type_number_t host_size = HOST_BASIC_INFO_COUNT;
	host_basic_info_data_t info;
	if (host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&info, &host_size) == KERN_SUCCESS) {
		return info.max_mem;
	}
	return 0;
}

uint64_t mvkGetAvailableMemorySize() {
#if MVK_IOS
	if (mvkOSVersionIsAtLeast(13.0)) { return os_proc_available_memory(); }
#endif
	mach_port_t host_port;
	mach_msg_type_number_t host_size;
	vm_size_t pagesize;
	host_port = mach_host_self();
	host_size = HOST_VM_INFO_COUNT;
	host_page_size(host_port, &pagesize);
	vm_statistics_data_t vm_stat;
	if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) == KERN_SUCCESS ) {
		return vm_stat.free_count * pagesize;
	}
	return 0;
}

uint64_t mvkGetUsedMemorySize() {
	task_vm_info_data_t task_vm_info;
	mach_msg_type_number_t task_size = TASK_VM_INFO_COUNT;
	if (task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&task_vm_info, &task_size) == KERN_SUCCESS) {
		return task_vm_info.phys_footprint;
	}
	return 0;
}

