// A small task model in Swift: an enum, a protocol, a struct with a
// computed property, optionals, and higher-order functions.
import Foundation

enum Priority: Int, CaseIterable {
    case low = 1, normal, high
}

protocol Summarizable {
    var summary: String { get }
}

struct Task: Summarizable {
    let title: String
    var priority: Priority = .normal
    var done: Bool = false

    var summary: String {
        let box = done ? "[x]" : "[ ]"
        return "\(box) \(title) (priority \(priority.rawValue))"
    }
}

struct TaskList {
    private(set) var tasks: [Task] = []

    mutating func add(_ task: Task) {
        tasks.append(task)
    }

    func next() -> Task? {
        tasks.filter { !$0.done }.max { $0.priority.rawValue < $1.priority.rawValue }
    }
}

var list = TaskList()
list.add(Task(title: "Write tests", priority: .high))
list.add(Task(title: "Ship release"))

for task in list.tasks {
    print(task.summary)
}

if let up = list.next() {
    print("next up: \(up.title)")
}
