//
//  WorkspaceOneSDK.swift
//  WorkspaceOneSdk
//
//  Created by VMWare, Inc.
//  Copyright © 2020 VMware, Inc. All rights reserved.
//  This product is protected by copyright and intellectual property laws in the United States and other countries as well as by international treaties.
//  WorkspaceOne products may be covered by one or more patents listed at http:www.vmware.com/go/patents.
//

import Foundation
import React
import WorkspaceOneSDKBridge

@objc(WorkspaceOneSdk)
class WorkspaceOneSdk: RCTEventEmitter, WSOSDKBridgeDelegate{
    
    
    
    static let CALLBACK_SCHEME = "awsdkcallback"
    
    static let ERROR_DOMAIN = "com.error.ws1sdk"
    static let EVENT_INIT_SUCCESS = "initSuccess"
    static let EVENT_INIT_FAILURE = "initFailure"
    static let EVENT_WIPE = "wipe"
    static let EVENT_LOCK = "lock"
    static let EVENT_UNLOCK = "unlock"
    static let EVENT_STOP_NETWORK_ACTIVITY = "stopNetworkActivity"
    static let EVENT_RESUME_NETWORK_ACTIVITY = "resumeNetworkActivity"
    static let EVENT_IS_COMPROMISED = "isCompromised"
    static let EVENT_IS_ENROLLED = "isEnrolled"
    static let ERROR_NO_GROUP = ("no_groupId", "missing groupId")
    static let ERROR_NO_USERNAME = ("no_userName", "missing userName")
    static let ERROR_NO_SERVERNAME = ("no_serverName", "missing serverName")
    static let ERROR_NO_CUSTM_SETTINGS = ("no_customSettings", "missing customSettings")
    var wsosdkBridge : WSOSBridge =  WorkspaceOneSDKBridge.WSOSBridge.sharedInstance()
    
    var hasListeners : Bool = false
    /*
     * requiresMainQueueSetup React Native Moduule.
     */
    @objc
    static override func requiresMainQueueSetup() -> Bool {
        return true
    }
    
    /*
     * Initialize the SDKBridge and Start SDK.
     */
    func pluginInitialize(){
        self.wsosdkBridge.bridgeDelegate = self
        self.wsosdkBridge.startWorkspaceOneSDK()
    }
    
    /*
     * RCTEventEmitter : Delegate Method startObserving.
     */
    override func startObserving() {
        self.hasListeners = true
    }
    
    /*
     * RCTEventEmitter : Delegate Method stopObserving.
     */
    override func stopObserving() {
        self.hasListeners = false
    }
    
    /*
     * RCTEventEmitter : Delegate Method for Supported Events.
     */
    override func supportedEvents() -> [String]! {
        return [WorkspaceOneSdk.EVENT_INIT_SUCCESS,
                WorkspaceOneSdk.EVENT_INIT_FAILURE,
                WorkspaceOneSdk.EVENT_WIPE,
                WorkspaceOneSdk.EVENT_LOCK,
                WorkspaceOneSdk.EVENT_UNLOCK,
                WorkspaceOneSdk.EVENT_STOP_NETWORK_ACTIVITY,
                WorkspaceOneSdk.EVENT_RESUME_NETWORK_ACTIVITY,
                WorkspaceOneSdk.EVENT_IS_COMPROMISED,
                WorkspaceOneSdk.EVENT_IS_ENROLLED];
    }
   
    /*
     * Start SDK.
     */
    @objc(startSDK)
    func startSDK(){
        self.pluginInitialize()
    }
    
    /*
     * Group ID .
     */
    @objc(groupId:rejecter:)
    func groupId(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){

        if let groupId = self.wsosdkBridge.groupId(){
            resovle(groupId)
        }
        else{
            let error = NSError(domain:WorkspaceOneSdk.ERROR_DOMAIN, code: 1, userInfo: [:])
            reject(WorkspaceOneSdk.ERROR_NO_GROUP.0, WorkspaceOneSdk.ERROR_NO_GROUP.1, error)

        }
    }
    
    /*
     * Logged In Current User.
     */
    @objc(userName:rejecter:)
    func userName(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        if let userName = self.wsosdkBridge.username(){
            resovle(userName)
        }
        else{
            let error = NSError(domain:WorkspaceOneSdk.ERROR_DOMAIN, code: 1, userInfo: [:])
            reject(WorkspaceOneSdk.ERROR_NO_USERNAME.0, WorkspaceOneSdk.ERROR_NO_USERNAME.1, error)

        }
    }
    
    /*
     * Server URL of Current User.
     */
    @objc(serverName:rejecter:)
    func serverName(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        if let serverName = self.wsosdkBridge.serverName(){
            resovle(serverName)
        }
        else{
            let error = NSError(domain:WorkspaceOneSdk.ERROR_DOMAIN, code: 1, userInfo: [:])
            reject(WorkspaceOneSdk.ERROR_NO_SERVERNAME.0, WorkspaceOneSdk.ERROR_NO_SERVERNAME.1, error)

        }
    }
    /*
     * Restriction Flag to Enable Copy Paste.
     */
    @objc(allowCopyPaste:rejecter:)
    func allowCopyPaste(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        resovle(self.wsosdkBridge.allowCopyPaste())
    }
    /*
     * Restriction Flag for Allowing Offline Access.
     */
    @objc(allowOffline:rejecter:)
    func allowOffline(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        resovle(self.wsosdkBridge.allowOffline())
    }
    
    /*
     * Restriction Flag to Restrict Document to Apps.
     */
    @objc(restrictDocumentToApps:rejecter:)
    func restrictDocumentToApps(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        resovle(self.wsosdkBridge.restrictDocumentToApps())
    }
    
    /*
     * Allowed Application list.
     */
    @objc(allowedApplications:)
    func allowedApplications(_ resovle:RCTResponseSenderBlock){
            resovle( self.wsosdkBridge.allowedApplications())
    }
    
    /*
     * Custom Settings.
     */
    @objc(customSettings:rejecter:)
    func customSettings(_ resovle:RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        if let customSettings = self.wsosdkBridge.customSettings(){
            resovle(customSettings)
        }
        else{
            let error = NSError(domain:WorkspaceOneSdk.ERROR_DOMAIN, code: 1, userInfo: [:])
            reject(WorkspaceOneSdk.ERROR_NO_CUSTM_SETTINGS.0, WorkspaceOneSdk.ERROR_NO_CUSTM_SETTINGS.1, error)

        }
    }
    
    /*
     * Flag for Device is Compliant.
     */
    @objc(isCompliant:rejecter:)
    func isCompliant(_ resolve:@escaping RCTPromiseResolveBlock,rejecter reject: RCTPromiseRejectBlock){
        self.wsosdkBridge.isCompliant { status in
            var statusArray: [Bool] = []
            statusArray.append(status)
            resolve(statusArray)
        }
    }
    
    /*
     * Flag for Device is Compromised.
     */
    @objc(isCompromised:)
    func isCompromised(_ resolve:@escaping  RCTResponseSenderBlock){
        self.wsosdkBridge.isCompromised { status in
            var statusArray: [Bool] = []
            statusArray.append(status)
            resolve(statusArray)
        }
    }
    
    /*
     * Flag for Device is Enrolled.
     */
    @objc(isEnrolled:rejecter:)
    func isEnrolled(_ resolve:@escaping RCTResponseSenderBlock, reject:@escaping RCTResponseErrorBlock){
        self.wsosdkBridge.isEnrolled { status, error in
            guard error != nil else
            {
                var statusArray: [Any] = []
                statusArray.append(status)
                resolve(statusArray)
                return
            }
            reject(error)
        }
    }
    
    /*
     * Open File.
     */
    @objc(openFile:resolve:rejecter:)
    func openFile(path: String, resovle:RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock){
        resovle(self.wsosdkBridge.open(filePath: path))
    }
    
    /*
     * Register Token for APNS.
     */
    @objc(registerPushNotificationToken:)
    func registerPushNotificationToken(token: String){
        self.wsosdkBridge.registerPushNotificationToken(token: token)
    }
    
    /*
     * Initialize Success Call back.
     */
    func initSuccess() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_INIT_SUCCESS, body: [:])
        }
    }
    
    /*
     * Initialize Failure call back.
     */
    func initFailure() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_INIT_FAILURE, body: [:])
        }
    }
    
    /*
     * Wipe Data call back.
     */
    func wipe() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_WIPE, body: [:])
        }
    }
    
    /*
     * Lock Device call back.
     */
    func lock() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_LOCK, body: [:])
        }
    }
    
    /*
     * Unlock Device call back.
     */
    func unlock() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_UNLOCK, body: [:])
        }
    }
    
    /*
     * Stop Network Activity call back.
     */
    func stopNetworkActivity(_ networkActivityStatus: Int) {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_STOP_NETWORK_ACTIVITY, body: [:])
        }
    }
    
    /*
     * Resume Network Activity call back.
     */
    func resumeNetworkActivity() {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_RESUME_NETWORK_ACTIVITY, body: [:])
        }
    }
    
    /*
     * IS Compromised call back.
     */
    func isCompromised(_ flag: Bool) {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_IS_COMPROMISED, body: [WorkspaceOneSdk.EVENT_IS_COMPROMISED:flag])
        }
    }
    
    /*
     * Is Compromised call back.
     */
    func isEnrolled(_ flag: Bool) {
        if hasListeners {
            self.sendEvent(withName: WorkspaceOneSdk.EVENT_IS_ENROLLED, body: [WorkspaceOneSdk.EVENT_IS_ENROLLED:flag])
        }
    }
    
}
