/*
 * 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

/*
 We have to create everything in a certain order:
 1. Packages
 2. Actions
 3. Triggers
 4. Rules
 */


public enum WhiskProjectError: Error {
    case duplicateNameError(name: String)
    case malformedManifestFile(name: String, cause: String)
    case ruleStateError(type: String, cause: String)
    case gitRequestError(cause: String)
    case unsupportedFeedType(cause: String)
}

enum Runtime {
    case swift3
    case nodeJS
    case java
    case python
}

public struct Package {
    let name: NSString
    let bindTo: String?
    let parameters: Array<[String:AnyObject]>?
}

public struct Trigger {
    let name: NSString
    let feed: NSString?
    let parameters: Array<[String:AnyObject]>?
}

public struct Rule {
    let name: NSString
    let trigger: NSString
    let action: NSString
}

public struct Sequence {
    let name: NSString
    let actions: Array<String>
}

public struct Action {
    let name: NSString
    let path: NSString
    var runtime: Runtime
    var parameters: Array<[String:AnyObject]>?
}

public struct Dependency {
    let name: NSString
    let url: NSString
    let version: NSString
}


open class ProjectReader {
    
    let BindingsFileName = "root-manifest.json"
    let ManifestFileName = "manifest.json"
    let DependencyDirectoryName = "Packages"
    
    var projectPath: String!
    var packageDict = [NSString: Package]()
    var actionsDict = [NSString: Action]()
    var triggerDict = [NSString: Trigger]()
    var dependenciesDict = [NSString: Dependency]()
    var ruleDict = [NSString: Rule]()
    var sequenceDict = [NSString: Sequence]()
    var manifestDict = [NSString: NSString]()
    var bindingsDict = [NSString: NSString]()
    
    var target: String?
    
    
    
    public init(path: String, repo: String? = nil, release: String? = nil, target: String?) throws  {
        
        self.target = target
        
        if let repo = repo {
            
            if let release = release {
                do {
                    
                    let group = DispatchGroup()
                    
                    let zipFilePath = "\(repo)/archive/\(release).zip"
                    try Git.cloneGitRepo(zipFilePath, toPath: path, group: group)
                    
                    switch group.wait(timeout: DispatchTime.distantFuture) {
                    case DispatchTimeoutResult.success:
                        let projectName = (repo as NSString).lastPathComponent
                        projectPath = "\(path)/\(projectName)-\(release)/src"
                        break
                    case DispatchTimeoutResult.timedOut:
                        throw WhiskProjectError.gitRequestError(cause: "Failure cloning repo \(repo): request timed out.")
                    }
                    
                } catch {
                    print("Error cloning repo \(error)")
                }
            } else {
                throw WhiskProjectError.gitRequestError(cause: "Cannot clone, release version must be specified ")
            }
        } else {
            projectPath = path
        }
    }
    
    open func dumpProjectStructure() {
        print("Packages:")
        print("=========")
        for (name, package) in packageDict {
            print("   name:\(name), package: \(package)")
        }
        
        print("Actions:")
        print("=========")
        for (name, action) in actionsDict {
            print("   name:\(name), path:\(action.path), runtime: \(action.runtime), parameters: \(action.parameters)")
        }
        
        print("Sequences:")
        print("=========")
        for (name, sequence) in sequenceDict {
            print("   name:\(name), sequence: \(sequence)")
        }
        
        print("Triggers:")
        print("=========")
        for (name, trigger) in triggerDict {
            print("   name:\(name), trigger:\(trigger)")
        }
        
        print("Rules:")
        print("=========")
        for (name, rule) in ruleDict {
            print("   name:\(name), rule:\(rule)")
        }
        
        print("Bindings:")
        print("=========")
        for (name, path) in bindingsDict {
            print("   name: \(name), path: \(path)")
        }
        
        
        print("Manifest:")
        print("=========")
        for (name, path) in manifestDict {
            print("   name: \(name), path: \(path)")
        }
        
        print("Dependencies:")
        print("=============")
        for (name, dependency) in dependenciesDict {
            print("   name: \(name), dependency: \(dependency)")
        }
        
    }
    
    open func readRootDependencies(_ clone: Bool) throws {
        
        let path = projectPath+"/"+BindingsFileName
        let json = try ManifestReader.parseJson(path as NSString)
        
        
        if let dependencies = json["dependencies"] {
            for dependency in dependencies as! Array<[String:AnyObject]> {
                guard let url = dependency["url"] as? NSString else {
                    clearAll()
                    throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of dependency missing url")
                }
                
                var repo = url as String
                
                if url.pathExtension == "git" {
                    
                    repo = String((repo as String).characters.dropLast(4))
                }
                
                let name = (repo as NSString).lastPathComponent as NSString
                
                var ver = "master"
                if let version = dependency["version"] as? NSString {
                    ver = version as String
                }
                
                let dep = Dependency(name: name as NSString, url: repo as NSString, version: ver as NSString)
                dependenciesDict[name] = dep
            }
        }
        
        try readDependencies(clone)
    }
    
    open func readProjectDirectory() throws {
        // read project directory
        try readDirectory(projectPath, isDependency: false)
        
        // read independent directories
    }
    
    open func readDependencies(_ clone: Bool) throws {
        for (name, dependency) in dependenciesDict {
            
            let group = DispatchGroup()
            
            let zipFilePath = "\(dependency.url)/archive/\(dependency.version).zip"
            if clone == true {
                try Git.cloneGitRepo(zipFilePath, toPath: projectPath+"/Packages/", group: group)
            }
            
            switch group.wait(timeout: DispatchTime.distantFuture) {
            case DispatchTimeoutResult.success:
                let packagePath = (name as String)+"-"+(dependency.version as String)
                let depPath = projectPath+"/Packages/"+packagePath+"/src"
                try readDirectory(depPath, isDependency: true)
                break
            case DispatchTimeoutResult.timedOut:
                break
            }
            
        }
    }
    
    open func detectXcode(_ path: String) -> (isXcode: Bool, projectName: NSString?) {
        let fileManager = FileManager.default
        if let enumerator: FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: path) {
            while let item = enumerator.nextObject() as? NSString {
                if item.pathComponents.count == 1 {
                    if item.pathExtension == "xcodeproj" {
                        return (isXcode: true, projectName: "\(path)/\(item)" as NSString)
                    }
                }
            }
        }
        return (isXcode: false, projectName: nil)
    }
    
    open func readDirectory(_ dirPath: String, isDependency: Bool) throws {
        
        let isXcode = detectXcode(dirPath)
        
        if isXcode.isXcode == false {
            let dir: FileManager = FileManager.default
            
            if let enumerator: FileManager.DirectoryEnumerator = dir.enumerator(atPath: dirPath) {
                
                var packageDir = "/"
                var maxDepth = 2
                
                if isDependency == true {
                    maxDepth = 4
                }
                while let item = enumerator.nextObject() as? NSString {
                    
                    // only check 2 levels down
                    if item.pathComponents.count <= maxDepth {
                        var isDir = ObjCBool(false)
                        let fullPath = dirPath+"/\(item)"
                        
                        if dir.fileExists(atPath: fullPath, isDirectory: &isDir) == true {
                            if isDir.boolValue == true {
                                
                                if item.pathComponents[0] != packageDir && item.pathComponents[0] != DependencyDirectoryName {
                                    packageDir = item.pathComponents[0]
                                    if packageDir.hasPrefix(".") == false {
                                        packageDict[item] = Package(name: item, bindTo: nil, parameters: nil)
                                    }
                                }
                                
                            }  else if item.hasSuffix(".swift") {
                                try addAction(fullPath as NSString, item: item, runtime: .swift3)
                            }  else if item.hasSuffix(".js") {
                                try addAction(fullPath as NSString, item: item, runtime: .nodeJS)
                            } else if item.hasSuffix(".json") {
                                
                                // in subdirectories we only look for manifest files
                                if item.pathComponents.count > 1 {
                                    
                                    // ignore hidden directories
                                    if item.pathComponents[0].hasPrefix(".") == false {
                                        
                                        let name = item.lastPathComponent
                                        let package = item.pathComponents[0]
                                        let qualifiedName = "\(package)/\(name)" as NSString
                                        
                                        if name == "\(package)-\(ManifestFileName)" {
                                            manifestDict[qualifiedName] = fullPath as NSString
                                        }
                                    }
                                } else {
                                    
                                    // in root dir, we look for bindings and manifest files
                                    if item == BindingsFileName as NSString {
                                        bindingsDict[item] = fullPath as NSString
                                    }
                                }
                            }
                        }
                    }
                    
                }
                
                try self.processManifestFiles(self.bindingsDict)
                try self.processManifestFiles(self.manifestDict)
            }
        } else {
            
            print("Found xcode directory \(isXcode.projectName!)" )
            let xcodeProject = WhiskTokenizer(from: dirPath, to:projectPath, projectFile: isXcode.projectName!, target: target)
            
            do {
                let xcodeTuple = try xcodeProject.readXCodeProjectDirectory()
                
                for entity in xcodeTuple.actions{
                    actionsDict[entity.name] = entity
                }
                
                for entity in xcodeTuple.triggers {
                    triggerDict[entity.name] = entity
                }
                
                for entity in xcodeTuple.rules {
                    print("Processing rule \(entity.name)")
                    ruleDict[entity.name] = entity
                }
                
                for entity in xcodeTuple.sequences {
                    sequenceDict[entity.name] = entity
                }
                
                
            } catch {
                print("Error reading xcode project \(error)")
            }
        }
    }
    
    func addAction(_ fullPath: NSString, item: NSString, runtime: Runtime) throws {
        
        let name = (item.lastPathComponent as NSString).deletingPathExtension
        
        if item.pathComponents.count > 1 {
            if item.pathComponents[0].hasPrefix(".") == false {
                
                let package = item.pathComponents[0]
                
                let fullName = "\(package)/\(name)" as NSString
                if !nameExists(fullName) {
                    actionsDict[fullName] = Action(name: fullName, path: fullPath, runtime: runtime, parameters: nil)
                } else {
                    clearAll()
                    throw WhiskProjectError.duplicateNameError(name:fullName as String)
                }
            }
        } else {
            if !nameExists(name as NSString) {
                actionsDict[name as NSString] = Action(name: name as NSString, path: fullPath, runtime: runtime, parameters: nil)
            } else {
                clearAll()
                throw WhiskProjectError.duplicateNameError(name: name)
            }
        }
    }
    
    func nameExists(_ name: NSString) -> Bool {
        if actionsDict[name] != nil || packageDict[name] != nil || triggerDict[name] != nil || ruleDict[name] != nil || sequenceDict[name] != nil {
            return true
        }
        
        return false
    }
    
    func processManifestFiles(_ manifest: [NSString: NSString]) throws {
        
        for (name, path) in manifest {
            
            let json = try ManifestReader.parseJson(path)
            
            var prefix = ""
            if name.pathComponents.count > 1 {
                prefix = name.pathComponents[0] + "/"
            }
            
            // Check these items for a root manifest only
            if prefix == "" {
                
                // process packages
                if let packages = json["bindings"] {
                    for package in packages as! Array<[String:AnyObject]> {
                        
                        guard let itemName = package["name"] as? String, let bindTo = (package["bindTo"]) as? String else {
                            clearAll()
                            throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of package binding missing name or bindTo")
                        }
                        
                        let parameters = package["parameters"] as? Array<[String:AnyObject]>
                        let item = Package(name: itemName as NSString, bindTo: bindTo, parameters: parameters)
                        packageDict[itemName as NSString] = item
                        
                    }
                }
                
                // process triggers
                if let triggers = json["triggers"] {
                    for trigger in triggers as! Array<[String:AnyObject]> {
                        
                        guard let itemName = trigger["name"] as? String else {
                            clearAll()
                            throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of trigger missing name")
                        }
                        
                        let parameters = trigger["parameters"] as? Array<[String:AnyObject]>

                        let feed = trigger["feed"] as? NSString
                        let item = Trigger(name: itemName as NSString, feed: feed, parameters: parameters)
                        triggerDict[itemName as NSString] = item
                    }
                    
                }
                
                
                // process rules
                if let rules = json["rules"] {
                    for rule in rules as! Array<[String:AnyObject]> {
                        
                        guard let itemName = rule["name"] as? String, let triggerName = rule["trigger"] as? String, let actionName = rule["action"] as? String else {
                            clearAll()
                            throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of rule missing name, trigger, or action")
                        }
                        
                        let item = Rule(name: itemName as NSString, trigger: triggerName as NSString, action: actionName as NSString)
                        ruleDict[itemName as NSString] = item
                    }
                    
                }
            }
            
            
            // check these for all manifest files
            // process sequences
            if let sequences = json["sequences"] {
                for sequence in sequences as! Array<[String:AnyObject]> {
                    
                    guard let itemName = sequence["name"] as? String, let actions = sequence["actions"] as? Array<String> else {
                        clearAll()
                        throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of sequence missing name or action list")
                    }
                    
                    let item = Sequence(name: prefix+itemName as NSString, actions: actions)
                    sequenceDict[ (prefix+itemName) as NSString] = item
                }
            }
            
            // process package parameters
            if let packageParams = json["packageParameters"] as? Array<[String:AnyObject]> {
                let packageName = name.pathComponents[0] as NSString
                if let item = packageDict[packageName] {
                    packageDict[packageName] = Package(name: packageName, bindTo: item.bindTo, parameters: packageParams)
                }
            }
            
            // process action parameters
            if let actionParams = json["actionParameters"] {
                for action in actionParams as! Array<[String:AnyObject]> {
                    
                    guard let itemName = action["action"] as? String else {
                        clearAll()
                        throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Declaration of action parameters in manfiest file is missing \'action\' attribute")
                    }
                    
                    if let item = actionsDict[(prefix+itemName) as NSString] {
                        var runtime = item.runtime
                        if let kind = action["kind"] as? String {
                            if runtime == Runtime.swift3 && kind == "swift:3" {
                                runtime = Runtime.swift3
                            }
                        }
                        
                        let parameters = action["parameters"] as? Array<[String:AnyObject]>
                        actionsDict[(prefix+itemName) as NSString] = Action(name: (prefix+itemName) as NSString, path: item.path, runtime: runtime, parameters: parameters)
                        
                    } else {
                        clearAll()
                        throw WhiskProjectError.malformedManifestFile(name: path as String, cause: "Setting parameters for an action \(itemName) that does not exist")
                    }
                    
                }
            }
        }
    }
    
    func clearAll() {
        packageDict.removeAll()
        actionsDict.removeAll()
        triggerDict.removeAll()
        ruleDict.removeAll()
        sequenceDict.removeAll()
        manifestDict.removeAll()
        bindingsDict.removeAll()
        dependenciesDict.removeAll()
    }
}

