#include "sys/osx/filesystem.h"

#include <CoreFoundation/CoreFoundation.h>
#include <objc/runtime.h>

#include <string>

/* These constants are defined in Foundation but not
 * exposed to CoreFoundation users.
*/
static constexpr unsigned long NSApplicationSupportDirectory = 14;
static constexpr unsigned long NSUserDomainMask = 1;

extern "C" {
	CFArrayRef NSSearchPathForDirectoriesInDomains(unsigned long directory, unsigned long domainMask, BOOL expandTilde);
}

namespace osx {

bool GetApplicationSupportDirectory(std::string& result) {
	// NSArray* strings = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, ON);
	const CFArrayRef strings = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true);
	if (!strings)
		return false;

	// NSIndex index = [strings count];
	const CFIndex count = CFArrayGetCount(strings);
	if (count < 1) {
		CFRelease(strings);
		return false;
	}

	// NSString* string = [strings objectAtIndex: 0];
	const CFStringRef string = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(strings, 0));
	if (!string) {
		CFRelease(strings);
		return false;
	}

	// result = [string UTF8String];
	result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1);
	if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8)) {
		CFRelease(strings);
		return false;
	}
	result.resize(result.find_first_of('\0'));

	return true;
}

} // namespace osx
