If you command wisely, you’ll be obeyed cheerfully.  Thomas Fuller

The command pattern is used to encapsulate details of how to invoke a method on an object in a way that allows the method to be invoked at a different time or by a different component. (Design Pattern in Swift)

protocol Command {
    func execute(receiver: Any)
}

//: A generic command can handle different kind of commands
class GenericCommand<T>: Command {
    private var instruction: T -> Void
    init(instruction: T -> Void){
        self.instruction = instruction
    }
    func execute(receiver: Any) {
        guard let safeReceiver = receiver as? T else {
            fatalError("Receiver is not an expected type")
        }
        instruction(safeReceiver)
    }
    class func createCommand(instruction: T -> Void) -> Command {
        return GenericCommand(instruction: instruction)
    }
}

protocol LatestCommand {
    func executeLatestCommand(receiver: Any)
}

//: A commandWrapper manages the execution of multiple commands or the lastest command
class CommandWrapper: Command, LatestCommand {
    private let commands: [Command]
    private var remainingCommands:[Command]
    init(commands: [Command]){
        self.commands = commands
        self.remainingCommands = commands
    }
    func execute(receiver: Any) {
        print("will excute all commands for \(receiver)")
        commands.map{$0.execute(receiver)}
        
    }
    func executeLatestCommand(receiver: Any){
        print("will execute the lastest command for \(receiver)")
        remainingCommands.removeLast().execute(receiver)
        print("\(remainingCommands.count) commands left.")
    }
}

class PeopleStandByCommand: Command {
    func execute(receiver: Any) {
        print("All people standby")
    }
}
class PrepareWeaponCommand: Command {
    func execute(receiver: Any) {
        print("Weapons are ready")
    }
}

class PrepareResourcesCommand: Command {
    func execute(receiver: Any) {
        print("All resources are ready")
    }
}

//: An operation that has manages the preparation of the war. It creates multiple commands which will be executed at runtime
class PrepareForWarOperation:CustomStringConvertible {
    private var commands:[Command] = []
    private var queue = dispatch_queue_create("arrayQueue", DISPATCH_QUEUE_SERIAL)
    var name: String
    var description: String { return name }
    init(kindom: String){
        print("PrepareForWar Operation for \(kindom) is created")
        self.name = kindom
        prepareEverything()
    }
    func notifyPeople(people: String){
        print("Notified \(people) about the war")
    }
    
    func prepareEverything(){
        addCommand(PrepareForWarOperation.notifyPeople, people: "people of \(name)")
        commands.append(PrepareResourcesCommand())
        commands.append(PrepareWeaponCommand())
        commands.append(PeopleStandByCommand())
    }

    private func addCommand(action: PrepareForWarOperation -> String -> Void, people: String){
        dispatch_sync(queue) { () -> Void in
            self.commands.append(GenericCommand.createCommand({ prep  in
                action(prep)(people)
            }))
        }
    }
    func getACommandWrap() -> protocol <Command,LatestCommand>? {
            var command: protocol <Command,LatestCommand>?
            dispatch_sync(queue) { () -> Void in
                command = CommandWrapper(commands: self.commands)
            }
            return command
    }
}
//: Testing
let p1 = PrepareForWarOperation(kindom: "Daria")
let commands = p1.getACommandWrap()
commands?.executeLatestCommand(p1)
commands?.execute(p1)
print("\n")

let p2 = PrepareForWarOperation(kindom: "Secila")
print("Use the same operation commands for another kindom called Secila")
commands?.execute(p2)

 

com