//
//  nitoInstaller.m
//  nitotvinstaller
//
//  Created by Kevin Bradley on 1/31/18.
//  Copyright © 2018 Kevin Bradley. All rights reserved.
//

#include <objc/runtime.h>
#include <libgen.h>
#include <dlfcn.h>
#include <CoreFoundation/CoreFoundation.h>
#ifdef ARM
#include <Foundation/Foundation.h> // NSObject
#endif
#import "nitoInstaller.h"
#include<stdio.h>
//#include<conio.h>
#include<string.h>

#define  CORE_SERVICE_FRAMEWORK  "/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices"

NSObject * workspace; // Intentionally void * so as to NOT involve @interface files

@interface LSApplicationWorkspace: NSObject

- (id)allApplications;
- (void)openApplicationWithBundleID:(NSString *)string;
- (id)defaultWorkspace;


@end

void get_string(char *string);

@implementation nitoInstaller

- (NSString *)airPlayVersionNumber
{
    NSDictionary *infoDictionary = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/PrivateFrameworks/AirPlaySupport.framework/Info.plist"];
    return infoDictionary[@"CFBundleVersion"];
    
}

+ (NSString *)getTextWithPrompt:(NSString *)thePrompt
{
    NSString *prompt = [NSString stringWithFormat:@"\n%@ ", thePrompt];
    fprintf(stdout, "%s", [prompt UTF8String]);
    
    NSString *thestring = [NSString.alloc initWithData:
                           [NSFileHandle.fileHandleWithStandardInput availableData]
                                              encoding:NSUTF8StringEncoding];
    
    return [thestring stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)tarPathForCurrentMode
{
    NSString *path = nil;
    switch (self.versionState) {
        case InstallVersionStateNine:
            
            path= @"/usr/bin/tar";
            break;
            
        case InstallVersionStateTenOne:
            
            path= @"/tmp/usr/bin/tar"; //need to verify
            break;
            
        case InstallVersionStateTenTwo:
            
            path= @"/usr/bin/tar";
            break;
            
        case InstallVersionStateEleven:
            
            path= @"/jb/usr/bin/tar";
            break;
        default:
            break;
    }
    return path;
}

- (NSString *)bootstrapPathForVersion:(NSString *)swVers
{
    NSString *bootstrapPath = @"https://nitosoft.com/ATV4/bootstraps/";
    {
        OurLog(@"srcvers: %@", swVers);
        if ([swVers compare:@"353.50" options:NSNumericSearch] != NSOrderedAscending)
        {
            OurLog(@"11.x or greater!");
            self.versionState = InstallVersionStateEleven;
            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
        } else if([swVers compare:@"320.20.1" options:NSNumericSearch] != NSOrderedAscending)
        {
            OurLog(@"10.2.2 or greater!");
            self.versionState = InstallVersionStateTenTwo;
            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap11.tar"];
        } else if([swVers compare:@"301.44.3" options:NSNumericSearch] != NSOrderedAscending)
        {
            OurLog(@"10.0 or greater");
            self.versionState = InstallVersionStateTenOne;
            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap9.tar"];
        } else {
            OurLog(@"9.0 or greater?");
            self.versionState = InstallVersionStateNine;
            bootstrapPath = [bootstrapPath stringByAppendingString:@"bootstrap9.tar"];
            
        }
        
    }
    return bootstrapPath;
}

+ (int)returnForProcess:(NSString *)call
{
    if (call==nil)
        return 0;
    char line[200];
    
    FILE* fp = popen([call UTF8String], "r");
    //NSMutableArray *lines = [[NSMutableArray alloc]init];
    if (fp)
    {
        while (fgets(line, sizeof line, fp))
        {
            NSString *s = [NSString stringWithCString:line encoding:NSUTF8StringEncoding];
            s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            OurLog(@"%@",s);
            // [lines addObject:s];
        }
    }
    int returnStatus = pclose(fp);
    return returnStatus;
}



int main(int argc, const char * argv[]) {

    NSString *runPath = [[NSFileManager defaultManager] currentDirectoryPath];
    nitoInstaller *installer = [nitoInstaller new];
    NSString *fileCheck = @"/var/lib/dpkg/status";
    OurLog(@"\n\nWelcome to the nitoTV 1.0 & bootstrap installer script!");
    OurLog(@"\nWe will detect your tvOS version and install the compatible bootstrap nitoTV, upon completion nitoTV should appear on your AppleTV\n\n");
    if ([[NSFileManager defaultManager] fileExistsAtPath:fileCheck])
    {
        //char *prompt = (char *)malloc(200*sizeof(char));
        char c;
        printf("\nIt appears you have already installed nitoTV and the bootstrap, it is NOT recommended to do this again, are you sure you want to continue? [y/n]?");
        c=getchar();
        while(c!='y' && c!='n')
        {
            if (c!='\n'){
                printf("[y/n]");
            }
            c=getchar();
        }
        //*prompt=c;
        //OurLog(@"%@",[NSString stringWithUTF8String:science]);
        
        if (c == 'n')
        {
            OurLog(@"\nsmart move... exiting\n");
            return 0;
        } else if (c == 'y') {
            OurLog(@"\nits your funeral....\n");
        }
    }

    [installer installPackageInPath:runPath];
    
    CFRunLoopRun();
    return 0;
    
}

- (void)openApp:(NSString *)bundleID;
{
    Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");    if (!LSApplicationWorkspace_class) {fprintf(stderr,"Unable to get Workspace class\n"); }    workspace = [LSApplicationWorkspace_class performSelector:@selector (defaultWorkspace)];    if (!workspace) {fprintf(stderr,"Unable to get Workspace\n"); }
    void *CS_handle = dlopen (CORE_SERVICE_FRAMEWORK, RTLD_NOW);    if (!CS_handle) {
        fprintf(stderr,"Can't find %s!\n", CORE_SERVICE_FRAMEWORK);
        return;
    }
    
    if (workspace){
        [workspace performSelector:@selector(openApplicationWithBundleID:) withObject:(id) bundleID ];
    }
    
    
}

- (void)installPackageInPath:(NSString *)thePath
{
    NSString *bootstrapPath = [self bootstrapPathForVersion:[self airPlayVersionNumber]];
    
    NSURL *url = [NSURL URLWithString:bootstrapPath];
    OurLog(@"Downloading file: %@", bootstrapPath);
    NSString *downloadLocation = [thePath stringByAppendingPathComponent:bootstrapPath.lastPathComponent];
    
    
    self.downloader = [URLDownloader new];
    [self.downloader downloadFileWithURL:url toLocation:downloadLocation withCredential:nil completed:^(NSString *downloadedFile) {
        OurLog(@"Download complete: %@", downloadedFile);
        
        OurLog(@"Installing...");
        NSString *tarPath = [self tarPathForCurrentMode];
        NSString *installString = [NSString stringWithFormat:@"%@ fxpv %@ -C / ; /usr/libexec/substrate ; /usr/bin/uicache  ; /bin/bash /usr/libexec/nito/firmware.sh ; rm /var/mobile/Library/Preferences/Featured.plist", tarPath, downloadedFile];
        
        OurLog(@"install string: %@", installString);
        
        
        [nitoInstaller returnForProcess:installString];
        if (self.versionState == InstallVersionStateNine)
        {
            [nitoInstaller returnForProcess:@"/usr/bin/killall -9 PineBoard HeadBoard lsd nitoTV"];
        }
        
        
        sleep(10);
        
        [self openApp:@"com.nito.nitoTV4"];
        
         CFRunLoopStop(CFRunLoopGetCurrent());
    }];

}

@end
