/*
* Copyright 2015-2016 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Foundation

/*

Hold the Whisk access key and access token.  The session token and jwtToken can be used to implement
custom authentication flows

*/
public struct WhiskCredentials {
    public init(accessKey: String?, accessToken: String?, sessionToken:String? = nil, jwtToken: String? = nil) {
        self.accessToken = accessToken
        self.accessKey = accessKey
        self.sessionToken = sessionToken
        self.jwtToken = jwtToken
    }
    
    // whisk credentials
    public var accessKey: String?
    public var accessToken: String?
    public var sessionToken: String?
    
    // optional app credentials
    public var appKey: String?
    public var appSecret: String?
    
    // optional token for custom authentication flow
    public var jwtToken: String?
}

/* Error types for Whisk calls */
public enum WhiskError: ErrorType {
    case HTTPError(description: String, statusCode: Int, url: String) // something went wrong with the http call
    case JsonError(description: String) // json wasn't right
    case CredentialError(description: String) // something is wrong with the whisk credentials
    case QualifiedNameFormat(description: String) // something is wrong in qualified name
    case WhiskProcessingError(description: String, errorCode: Int) // something went wrong on the whisk side.
}

/* Type of Whisk operation requested */
enum WhiskType {
    case Action
    case Trigger
}

/* Main class to hold the calls to invoke Actions and fire Triggers */
public class Whisk {
    
    // Secrets needed to call Whisk API
    let AccessKey: String? // Whisk key
    let AccessToken: String? // Whisk token
    let AppKey: String? // application Key (currently not used)
    let AppSecret: String? // application Secret (curently not used)
    
    // api Host for Whisk backend
    public var whiskBaseURL: String?
    
    // set to non-nil if using a custom session
    public var urlSession: NSURLSession?
    
    public var verboseReplies: Bool = false
    
    // Set these if you want to run unit tests and mock
    // calls to Whisk backend.
    public var useMock: Bool = false
    public var mockReply: [String: AnyObject]?
    public var mockError: WhiskError?
    
    
    // return base URL of backend including common path for all API calls
    public var baseURL: String? {
        set {
            if let url = newValue {
                
                let c = url.characters.last
                
                let separater =  c == "/" ? "" : "/"
                
                whiskBaseURL = url + separater + "api/v1/"
                
            } else {
                whiskBaseURL = nil
            }
        }
        get {
            return whiskBaseURL
        }
    }
    
    // Initialize with credentials, region currently not used
    public init(credentials: WhiskCredentials, region: String = "US-East-1") {
        // initialize
        AccessKey = credentials.accessKey
        AccessToken = credentials.accessToken
        AppKey = credentials.appKey
        AppSecret = credentials.appSecret
        
    }
    
    
    /* Base function to fire Whisk Trigger identified by qualified name */
    public func fireTrigger(qualifiedName qualifiedName: String, parameters: AnyObject? = nil, callback: (reply: Dictionary<String,AnyObject>?, error:WhiskError?)->Void) throws {
        
        let pathParts = try Whisk.processQualifiedName(qualifiedName)
        try fireTrigger(name: pathParts.name, package: pathParts.package, namespace: pathParts.namespace, parameters: parameters, callback: callback)
    }
    
    /* Base function to invoke Whisk Action identified by qualified name */
    public func invokeAction(qualifiedName qualifiedName: String, parameters: AnyObject?, hasResult: Bool = false, callback: (reply: Dictionary<String,AnyObject>?, error:WhiskError?)->Void) throws {
        
        let pathParts = try Whisk.processQualifiedName(qualifiedName)
        try invokeAction(name: pathParts.name, package: pathParts.package, namespace: pathParts.namespace, parameters: parameters, hasResult: hasResult, callback: callback)
    }
    
    
    /* Base function to fire Whisk Trigger identified by components */
    public func fireTrigger(name name: String, package: String? = nil, namespace: String = "_", parameters: AnyObject? = nil, callback: (reply: Dictionary<String,AnyObject>?, error:WhiskError?)->Void) throws {
        
        if let accessKey = AccessKey, accessToken = AccessToken {
            try httpRequestWhiskAPI(accessKey: accessKey, accessToken: accessToken, namespace: namespace, verb: "POST", type: .Trigger, package: package, name:name, parameters: parameters, isSync: false, callback: { (jsonArray, error) in
                if let error = error {
                    callback(reply: nil, error: error)
                } else {
                    callback(reply: jsonArray, error: nil)
                }
            })
        } else {
            throw WhiskError.CredentialError(description: "Access key and token not set")
        }
        
        
    }
    
    /* Base function to invoke Whisk Action identified by components */
    public func invokeAction(name name: String, package: String? = nil, namespace: String = "_", parameters: AnyObject?, hasResult:Bool = false, callback: (reply: Dictionary<String,AnyObject>?, error: WhiskError?)-> Void) throws {
        if let accessKey = AccessKey, accessToken = AccessToken {
            
            try httpRequestWhiskAPI(accessKey: accessKey, accessToken: accessToken, namespace: namespace, verb: "POST", type: .Action, package: package, name: name, parameters: parameters, isSync: hasResult, callback: {(jsonDict, error) in
                if let error = error {
                    callback(reply: nil, error: error)
                } else {
                    callback(reply: jsonDict, error: nil)
                }
                
            })
        } else {
            throw WhiskError.CredentialError(description: "Access key and token not set")
        }
        
    }
    
    /* can redirect call here, e.g. if mocking */
    func httpRequestWhiskAPI(accessKey accessKey: String, accessToken: String, namespace: String, verb: String, type: WhiskType, package: String?, name: String, parameters: AnyObject?, isSync: Bool, callback: (reply: Dictionary<String,AnyObject>?, error:WhiskError?) ->Void) throws {
        
        if useMock {
            callback(reply:mockReply, error: mockError)
            
        } else {
            try whiskAPI(accessKey: accessKey, accessToken: accessToken, namespace: namespace, verb: verb, type: type, package: package, name: name, parameters: parameters, isSync: isSync, callback: callback)
        }
    }
    
    
    /* Network call */
    func whiskAPI(accessKey accessKey: String, accessToken: String, namespace: String, verb: String, type: WhiskType, package: String?, name: String, parameters: AnyObject?, isSync: Bool, callback: (reply: Dictionary<String,AnyObject>?, error:WhiskError?) ->Void) throws {
        
        // set parameters
        var paramsIsDict = false
        if let parameters = parameters {
            if parameters is Dictionary<String, AnyObject> {
                paramsIsDict = true
            }
        }
        
        // set authorization string
        let loginString = NSString(format: "%@:%@", accessKey, accessToken)
        let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
        let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
        
        let typeStr: String!
        
        // set type
        switch type {
        case .Action:
            typeStr = "actions"
        case .Trigger:
            typeStr = "triggers"
        }
        
        // get base URL
        guard let actionURL = baseURL != nil ? baseURL : Config.getHostAndPath(type: typeStr) else {
            callback(reply: nil, error: WhiskError.HTTPError(description: "Base URL not set, try using whisk.baseUrl setting", statusCode: 400, url: "Undefined"))
            return
        }
        
        // append namespace and trigger/action path
        var syncName = "namespaces/"
        
        var namespaceStr = namespace
        
        if namespace.characters.count == 0 {
            namespaceStr = "_"
        }
        
        if let package = package {
            if package.characters.count == 0 {
                syncName = syncName + namespaceStr+"/"+typeStr+"/"+name
            } else {
                syncName = syncName + namespaceStr+"/"+typeStr+"/"+package+"/"+name
            }
        } else {
            syncName = syncName + namespaceStr+"/"+typeStr+"/"+name
        }
        
        // if action has results, specify as blocking
        if isSync == true {
            syncName += "?blocking=true"
        }
        
        // use this for verbose replies
        let restCall = actionURL+syncName
        
        guard let encodedPath = syncName.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) else {
            callback(reply: nil, error: WhiskError.HTTPError(description: "URL Encode error \(syncName)", statusCode: 400, url: restCall))
            return
        }
        
        syncName = encodedPath
        
        // create request
        guard let url = NSURL(string:actionURL+syncName) else {
            // send back error on main queue
            
            callback(reply: nil, error: WhiskError.HTTPError(description: "Malformed url", statusCode: 400, url: restCall))
            
            return
            
        }
        
        let request = NSMutableURLRequest(URL: url)
        request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        request.addValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
        request.HTTPMethod = verb
        
        // create JSON from parameters dictionary
        do {
            
            if let parameters = parameters {
                if paramsIsDict {
                    request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(parameters, options: NSJSONWritingOptions())
                } else {
                    if parameters is String {
                        let str = "{\"payload\":\"\(parameters as! String)\"}"
                        request.HTTPBody = str.dataUsingEncoding(NSUTF8StringEncoding)
                    } else {
                        let str = "{\"payload\": \(parameters)}"
                        request.HTTPBody = str.dataUsingEncoding(NSUTF8StringEncoding)
                    }
                }
            }
            
        } catch {
            print("Error parsing JSON in Whisk request: \(error)")
        }
        
        
        // retrieve session as default or use developer specified session
        let sess: NSURLSession!
        if let _ = urlSession {
            sess = urlSession
        } else {
            let sessConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
            sess = NSURLSession(configuration: sessConfig)
        }
        
        // perform network request
        let task = sess.dataTaskWithRequest(request) {
            data, response, error in
            let statusCode: Int!
            
            if let error = error {
                
                if let httpResponse = response as? NSHTTPURLResponse {
                    statusCode = httpResponse.statusCode
                } else {
                    statusCode = -1
                }
                // return network transport error call on main queue
                dispatch_async(dispatch_get_main_queue()) {
                    callback(reply: nil, error: WhiskError.HTTPError(description: "\(error.localizedDescription)", statusCode: statusCode, url: restCall))
                }
                
                return
                
            } else {
                
                if let httpResponse = response as? NSHTTPURLResponse {
                    statusCode = httpResponse.statusCode
                    do {
                        // success
                        if statusCode < 300 {
                            
                            switch verb {
                                // is an action invocation
                            case "POST":
                                var jsonDict = [String:AnyObject]()
                                
                                let respDict = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! Dictionary<String, AnyObject>
                                jsonDict = respDict
                                
                                
                                if let whiskError = jsonDict["error"] as? String {
                                    
                                    var errorCode = -1
                                    if let code = jsonDict["code"] as? Int {
                                        errorCode = code
                                    }
                                    // send back error on main queue
                                    dispatch_async(dispatch_get_main_queue()) {
                                        callback(reply: nil, error: WhiskError.WhiskProcessingError(description: "errorCode:\(errorCode), \(whiskError)", errorCode: errorCode))
                                    }
                                    
                                } else {
                                    
                                    var whiskReply = [String:AnyObject]()
                                    
                                    if self.verboseReplies == true {
                                        whiskReply = jsonDict
                                        
                                        // add the rest call made to verbose replies for debugging
                                        switch type {
                                        case .Action:
                                            whiskReply["actionUrl"] = restCall
                                        case .Trigger:
                                            whiskReply["triggerUrl"] = restCall
                                        }
                                        
                                    } else {
                                        let reply = jsonDict
                                        whiskReply["activationId"] = reply["activationId"]
                                        
                                        if isSync == true {
                                            if let whiskResponse = reply["response"] as? [String:AnyObject] {
                                                
                                                if let actionResult = whiskResponse["result"] {
                                                    
                                                    //if let payload = actionResult["payload"] {
                                                    
                                                    let payload:AnyObject? = actionResult
                                                    if payload is String {
                                                        do {
                                                            let payloadObj:AnyObject? = try NSJSONSerialization.JSONObjectWithData(payload!.dataUsingEncoding(NSUTF8StringEncoding)!, options:[])
                                                            whiskReply["result"] = (payloadObj as? [String:AnyObject])!
                                                        } catch {
                                                            print("Error parsing payload into JSON, defaulting to string")
                                                            whiskReply = ["result" : "\(payload!)"]
                                                        }
                                                    } else {
                                                        whiskReply["result"] = (payload as? [String:AnyObject])!
                                                    }
                                                    //}
                                                }
                                            }
                                        }
                                    }
                                    
                                    // send back successful response on main queue
                                    dispatch_async(dispatch_get_main_queue()) {
                                        callback(reply: whiskReply, error: nil)
                                    }
                                }
                                
                                // get info about actions/triggers
                                // not used right now
                            case "GET":
                                let jsonArray = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
                                let jsonDict:Dictionary<String, AnyObject> = ["array":jsonArray]
                                
                                dispatch_async(dispatch_get_main_queue()) {
                                    callback(reply: jsonDict, error: nil)
                                }
                                
                            default:
                                break
                                
                            }
                        } else {
                            dispatch_async(dispatch_get_main_queue()) {
                                callback(reply: nil, error: WhiskError.HTTPError(description: "Whisk returned HTTP error code", statusCode: statusCode, url:restCall))
                            }
                        }
                        
                    } catch {
                        print("Error parsing JSON from Whisk response: \(error)")
                        dispatch_async(dispatch_get_main_queue()) {
                            callback(reply: nil, error: WhiskError.JsonError(description: "\(error)"))
                        }
                    }
                }
            }
        }
        
        task.resume()
        
        
    }
    
    /* Convert qualified name string into component parts of action or trigger call */
    class func processQualifiedName(qName: String) throws -> (namespace:String, package: String?, name: String) {
        var namespace = "_"
        var package: String? = nil
        var name = ""
        var doesSpecifyNamespace = false
        
        if qName.characters.first == "/" {
            doesSpecifyNamespace = true
        }
        
        let pathParts = qName.characters.split { $0 == "/" }.map(String.init)
        
        if doesSpecifyNamespace == true {
            if pathParts.count == 2 {
                namespace = pathParts[0]
                name = pathParts[1]
            } else if pathParts.count == 3 {
                namespace = pathParts[0]
                package = pathParts[1]
                name = pathParts[2]
            } else {
                throw WhiskError.QualifiedNameFormat(description: "Cannot parse \(qName)")
            }
        } else {
            if pathParts.count == 1 {
                name = pathParts[0]
            } else if pathParts.count == 2 {
                package = pathParts[0]
                name = pathParts[1]
            } else {
                throw WhiskError.QualifiedNameFormat(description: "Cannot parse \(qName)")
            }
        }
        
        return (namespace, package, name)
    }
    
}


