//
//  AppDelegate.swift
//  masterkey
//
//  Created by Ian Kohl on 2/28/19.
//  Copyright © 2019 One Sky IT. All rights reserved.
//

//Open/Close
//quicktime - MP4
//Text
//Doc

import Cocoa
import OSAKit

enum ApplicationNameConstants: String {
    case PowerPointMac = "Microsoft PowerPoint"
    case PowerPointWin = "Microsoft Office PowerPoint"
    case Keynote = "Keynote"
    case LibreOffice = "LibreOffice"
    case AdobeAcrobat = "Adobe Acrobat Reader DC"
    case GoogleChrome = "Google Chrome"
    case VLC = "VLC"
}

extension ApplicationNameConstants: CaseIterable {}

extension String {
    func fileName() -> String {
        return NSURL(fileURLWithPath: self).deletingPathExtension?.lastPathComponent ?? ""
    }
    
    func fileExtension() -> String {
        return NSURL(fileURLWithPath: self).pathExtension ?? ""
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    var assistant:ApplicationAssistant!
    
    var openingFile = false
    
    //No window
    //@IBOutlet weak var window: NSWindow!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        if !openingFile {
            NSLog("Not opening a file. Displaying setup dialog...")
            if setupDialog() {
                NSLog("Proceeding to trigger all security warnings...")
                if triggerSecurity() {
                    NSLog("Presentation applications have been opened..")
                }
            }
        }
        
        NSLog("Terminating applicaiton...")
        terminateApplication()
    }
    
    func terminateApplication() {
        NSLog("Terminating...")
        NSApplication.shared.terminate(self)
    }
    
    func applicationWillTerminate(_ aNotification: Notification) {
        
    }
    
    func application(_ sender: NSApplication, openFile filename: String) -> Bool {
        NSLog("Version 2.0")
        
        openingFile = true
        
        //Used to open a group of files
        //let first_filename = filenames[0];
        
        //open a single file
        let filename_extension = String(filename.fileExtension().lowercased());
        
        NSLog("Filename Extension: \(filename_extension)")
        
        var assistantFlag = false
        
        //Args to pass to application - not currently used
        //var args = ""
        
        //once we are ready with a single presentation file (lowercase, valid ext) get into the switch
        switch filename_extension {
        case "pptx",
             "ppt",
             "pptmac",
             "pptxmac":
            NSLog("Mac PPT File...");
            assistant = PowerPointMacAssistant();
        case "pptxwin",
             "pptwin":
            NSLog("Windows PPT File...")
            assistant = PowerPointWindowsAssistant();
        case "pdf",
             "pdfmac":
            NSLog("PDF File...")
            //args = "pagemode=FullScreen"
            assistant = AcrobatAssistant();
        case "pdfwin":
            NSLog("PDF Windows File...")
            assistant = AcrobatWindowsAssistant();
        case "key":
            NSLog("Keynote File...")
            assistant = KeynoteAssistant();
        case "odp":
            NSLog("LibreOffice File...")
            assistant = LibreOfficeAssistant();
        case "mp4",
             "mkv",
             "mov",
             "mpeg",
             "avi",
             "flv",
             "ogg",
             "mp3",
             "ogv":
            NSLog("Video (VLC) File...")
            assistant = VideoAssistant();
        case "wmv":
            NSLog("Windows Video (VLC) File...")
            assistant = WindowsVideoAssistant();
        case "doc",
             "docx":
            NSLog("Microsoft Word Document...")
            assistant = WordMacAssistant();
        default:
            NSLog("Generic File...")
            assistantFlag = true
        }
        
        let legacyUtilities: LegacyUtilities = LegacyUtilities()
        
        if assistantFlag {
            NSLog("Is assistant...")
            legacyUtilities.undoMirror()
            //TODO: Window to mirror
            NSWorkspace.shared.openFile(filename)
        } else {
            if assistant.shouldUnmirror {
                legacyUtilities.undoMirror()
            }
            
            NSLog("Opening file...")
            NSWorkspace.shared.openFile(filename, withApplication: assistant.applicationName)
            NSLog("Sleeping...")
            sleep(assistant!.delay)
            NSLog("Activating application...")
            let apps = NSRunningApplication.runningApplications(withBundleIdentifier: assistant.bundleID)
            for app in apps as [NSRunningApplication] {
                if app.bundleIdentifier == assistant.bundleID {
                    app.activate(options: .activateIgnoringOtherApps)
                }
            }
           
            NSLog("Running Automation...")
            if self.runAutomation() {
                NSLog("Mirror check...")
                if assistant.mirrored {
                    NSLog("Mirroring...")
                    legacyUtilities.setupMirror()
                }
            }
        }
        
        //Start recording code
        var screens = 2

        //TODO: get actual number of screens as mirroring/unmirroring should be done at this point
        if assistant.mirrored {
            screens = 1
        }

        let utils = Utilities()
        let rec_result = utils.startRecording(filename: filename,num_screens: screens)
        NSLog("Recording result...")
        NSLog(rec_result)
        //End recording code
        
        // Return true for successfully opening the file.
        return true
    }
    
    //TODO: Merge this and security as it is the same code
    func runAutomation() -> Bool {
        NSLog("Run automation...")
        NSLog(assistant.scriptString)
        let script = OSAScript.init(source: assistant.scriptString, language: OSALanguage.init(forName: "JavaScript"));
        var compileError : NSDictionary?
        script.compileAndReturnError(&compileError)
        if let compileError = compileError {
            NSLog("Compile Error...")
            print(compileError);
            return false;
        }
        var scriptError : NSDictionary?
        let result = script.executeAndReturnError(&scriptError)
        if let scriptError = scriptError {
            NSLog("Print error...")
            NSLog(scriptError.description)
        }
        else if let result = result?.stringValue {
            NSLog("Result...")
            print(result)
        }
        
        return true
    }
    
    func triggerSecurity() -> Bool {
        NSLog("Trigger Security...")
        
        ApplicationNameConstants.allCases.forEach {
            let application_name = $0.rawValue
            let application_security_script = """
            var app = Application('\(application_name)')
            delay(1)
            app.activate()
            """
            executeSecurityScript(script: application_security_script)
        }
        
        let final_security_script = """
        var finder = Application('Finder')
        finder.activate()
        delay(1)
        var se = Application('System Events')
        se.keyCode(50)
        """
        NSLog(final_security_script)
        executeSecurityScript(script: final_security_script)
        
        return true
    }
    
    func executeSecurityScript(script: String) {
        let script = OSAScript.init(source: script, language: OSALanguage.init(forName: "JavaScript"));
        var compileError : NSDictionary?
        script.compileAndReturnError(&compileError)
        if let compileError = compileError {
            NSLog("Security Script Compile Error...")
            print(compileError);
        }
        var scriptError : NSDictionary?
        let result = script.executeAndReturnError(&scriptError)
        if let scriptError = scriptError {
            NSLog("Print security script error...")
            NSLog(scriptError.description)
        }
        else if let result = result?.stringValue {
            NSLog("Trigger Security Result...")
            print(result)
        }

    }
    
    func setupDialog() -> Bool {
        let alert = NSAlert()
        alert.messageText = "Are you setting up a new version of Master Key?"
        alert.informativeText = "If you answer Yes, each applicaiton (PowerPoint, Keynote, etc.) will open so that security permissions can be granted for automation for each application. If you answer no, no action will be taken and the application will exit immediately."
        alert.alertStyle = .warning
        alert.addButton(withTitle: "Yes")
        alert.addButton(withTitle: "No")
        return alert.runModal() == .alertFirstButtonReturn
    }
}


