#import <objc/runtime.h>
#import <notify.h>
#import <dlfcn.h>
#import <substrate.h>
#import <sys/utsname.h>
#import <UIKit/UIKit.h>
#import "TVSettingsTweakViewController.h"
extern const char *__progname;

#define NSLog(...)

#define PLIST_PATH_Settings "/var/mobile/Library/Preferences/com.nito.dalesdeadbug.plist"


static BOOL Enabled;
static __strong NSString* kCurrentiOSVersion = nil;
static __strong NSString* kCurrentDeviceType = nil;
static __strong NSString* kCurrentiOSVersionSpoof = nil; //no idea why theres were chars, just overcomplicating things.
const char * kCurrentDeviceTypeSpoof;
static __strong NSString* kUserAgent = @"User-Agent";
static __strong NSString* kFormatHeader = @"/%@ ";

%group itunesstoredHooks
%hook NSMutableURLRequest
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
{
	%log;
	//TODO: absolutely do NOT check this here every time... will be okay for now.
	NSDictionary *LowerInstallPrefs = [[[NSDictionary alloc] initWithContentsOfFile:@PLIST_PATH_Settings]?:[NSDictionary dictionary] copy];
	//HBLogInfo(@"###LowerInstallPrefs: %@", LowerInstallPrefs);
	Enabled = (BOOL)[[LowerInstallPrefs objectForKey:@"Enabled"]?:@YES boolValue];
	kCurrentiOSVersionSpoof = [LowerInstallPrefs objectForKey:@"SpoofVersion"]?:@"11.1";
	if(Enabled && field && value && kUserAgent && [field isEqualToString:kUserAgent] && kCurrentiOSVersion && kCurrentiOSVersionSpoof) {
		HBLogInfo(@"currentiOSVersion: %@ value: %@", kCurrentiOSVersion, value);
		if([value rangeOfString:kCurrentiOSVersion].location != NSNotFound) {
			//HBLogInfo(@"### are we inside here???");
			value = [value stringByReplacingOccurrencesOfString:[NSString stringWithFormat:kFormatHeader, kCurrentiOSVersion] withString:[NSString stringWithFormat:kFormatHeader, kCurrentiOSVersionSpoof]];
			//HBLogInfo(@"### are we inside here??? 2");
			//value = [value stringByReplacingOccurrencesOfString:[NSString stringWithFormat:kFormatHeader, kCurrentDeviceType] withString:[NSString stringWithFormat:kFormatHeader, [NSString stringWithUTF8String:kCurrentDeviceTypeSpoof]]];
			//HBLogInfo(@"### are we inside here??? 3");
		} else {
			
			HBLogInfo(@"#### value: %@ not found in %@", value, kCurrentiOSVersion);
			
			
		}
	}
	%orig(value, field);
}
%end
%end

%group installdHooks
%hook MIBundle

/*
- (BOOL)isApplicableToCurrentOSVersionWithError:(NSError *)error {
	
	%log;
	return YES;
}
*/
- (NSString*)minimumOSVersion
{
	%log;
	NSString* ret = %orig;
	ret = @"2.0";
	return ret;
}

/*
- (_Bool)isApplicableToCurrentDeviceCapabilitiesWithError:(id *)arg1
{
	%log;
	BOOL orig = %orig;
	return YES;
}
- (_Bool)isApplicableToOSVersion:(id)arg1 error:(id *)arg2{
	%log;
	BOOL orig = %orig;
	return YES;
}
- (_Bool)isApplicableToCurrentOSVersionWithError:(id *)arg1{
	%log;
	BOOL orig = %orig;
	return YES;
}
- (_Bool)isApplicableToCurrentDeviceFamilyWithError:(id *)arg1{
	%log;
	BOOL orig = %orig;
	return YES;
}
- (_Bool)isCompatibleWithDeviceFamily:(int)arg1{
	%log;
	BOOL orig = %orig;
	return YES;
}

- (NSArray *)supportedDevices
{
	NSArray* ret = %orig?:@[];
	if(kCurrentDeviceType && ![ret containsObject:kCurrentDeviceType]) {
		NSMutableArray* retMut = [ret mutableCopy];
		[retMut addObject:[kCurrentDeviceType copy]];
		ret = [retMut copy];
	}
	return ret;
}
*/
%end
%end

/* Set platform binary flag */
#define FLAG_PLATFORMIZE (1 << 1)

void platformize_me() {
    void* handle = dlopen("/usr/lib/libjailbreak.dylib", RTLD_LAZY);
    if (!handle) return;
    
    // Reset errors
    dlerror();
    typedef void (*fix_entitle_prt_t)(pid_t pid, uint32_t what);
    fix_entitle_prt_t ptr = (fix_entitle_prt_t)dlsym(handle, "jb_oneshot_entitle_now");
    
    const char *dlsym_error = dlerror();
    if (dlsym_error) return;
    
    ptr(getpid(), FLAG_PLATFORMIZE);
}

static void settingsChangedLowerInstall()
{	
	@autoreleasepool {
		NSDictionary *LowerInstallPrefs = [[[NSDictionary alloc] initWithContentsOfFile:@PLIST_PATH_Settings]?:[NSDictionary dictionary] copy];
		Enabled = (BOOL)[[LowerInstallPrefs objectForKey:@"Enabled"]?:@YES boolValue];
		kCurrentiOSVersionSpoof = [LowerInstallPrefs objectForKey:@"SpoofVersion"]?:@"11.1";
		//kCurrentiOSVersionSpoof = (const char*)(malloc([CurrentiOSVersionSpoof length]));
		//memcpy((void*)kCurrentiOSVersionSpoof,(const void*)CurrentiOSVersionSpoof.UTF8String, [CurrentiOSVersionSpoof length]);
		//((char*)kCurrentiOSVersionSpoof)[[CurrentiOSVersionSpoof length]] = '\0';
		NSString* CurrentDeviceTypeSpoof = [LowerInstallPrefs objectForKey:@"SpoofDevice"]?:@"AppleTV5,3";
		kCurrentDeviceTypeSpoof = (const char*)(malloc([CurrentDeviceTypeSpoof length]));
		memcpy((void*)kCurrentDeviceTypeSpoof,(const void*)CurrentDeviceTypeSpoof.UTF8String, [CurrentDeviceTypeSpoof length]);
		((char*)kCurrentDeviceTypeSpoof)[[CurrentDeviceTypeSpoof length]] = '\0';
	}
}

%group settingsHooks
/*
%hook TVSettingsMainViewController

- (id)loadSettingGroups {
	
	%log;
	NSArray* groups = %orig;
	TSKSettingGroup *group = groups[0];
	//[m +[<TSKSettingItem: 0x1ad71bc88> childPaneItemWithTitle:General description:(null) representedObject:(null) keyPath:(null) childControllerClass:TVSettingsGeneralViewController]
	Class theClass = NSClassFromString(@"TVSettingsTweakViewController");
	id testItem = [TSKSettingItem childPaneItemWithTitle:@"Tweaks" description:nil representedObject:nil keyPath:nil childControllerClass:theClass];
	HBLogDebug(@"testItem = %@", testItem);
	NSArray *settingsItems = [group valueForKey:@"settingItems"];
	HBLogDebug(@"settingsItems = %@", settingsItems);
	NSMutableArray *newItems = [settingsItems mutableCopy];
	//[newItems addObject:testItem];
	[newItems insertObject:testItem atIndex:7];
	HBLogDebug(@"newItems = %@", newItems);
	[group setSettingItems:newItems];
	
	return @[group];
}

%end
*/
%end

%ctor
{
	HBLogInfo(@"### DalesDeadBug reporting for duty!");
	//platformize_me();
	
	//HBDebugLog(@"Dales Dead Bug reporting for duty!");
	CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)settingsChangedLowerInstall, CFSTR("com.julioverne.lowerinstall/SettingsChanged"), NULL, CFNotificationSuspensionBehaviorCoalesce);
	settingsChangedLowerInstall();
	struct utsname systemInfo;
	uname(&systemInfo);
	kCurrentDeviceType = [NSString stringWithFormat:@"%s", systemInfo.machine];
	kCurrentiOSVersion = [NSString stringWithFormat:@"%@", [[UIDevice currentDevice] systemVersion]];
	if(strcmp(__progname, "itunesstored") == 0) {
		HBLogInfo(@"### DalesDeadBug: itunesstored");
		%init(itunesstoredHooks);
	} else if(strcmp(__progname, "installd") == 0){
		HBLogInfo(@"### DalesDeadBug: installd");
		%init(installdHooks);
	} else {
		%init(settingsHooks);
	}
}

