diff --git a/Bank.swift b/Bank.swift new file mode 100644 index 000000000..48883ea23 --- /dev/null +++ b/Bank.swift @@ -0,0 +1,60 @@ +// +// BankManager.swift +// Created by yagom. +// Copyright © yagom academy. All rights reserved. +// + +import Foundation + +final class Bank { + private var clients: [Client] = [] + private var tellers: [Teller] = [] + private var finishedClientNumber = 0 + private var businessTime: TimeInterval? + + func operateBank(teller: Int, client: [Client]) { + let openTime = Date() + + initTellers(teller) + clients = client + assignBusinessToTeller() + businessTime = Date().timeIntervalSince(openTime) + Dashboard.printCloseMessage(finishedClientNumber, businessTime) + closeBank() + } + + private func initTellers(_ number: Int) { + for windowNumber in 1...number { + tellers.append(Teller(windowNumber: windowNumber)) + } + } + + private func assignBusinessToTeller() { + let semaphore = DispatchSemaphore(value: 0) + var isContinue = true + + while isContinue { + for teller in self.tellers { + if self.clients.count == 0 { + isContinue = false + break + } + if teller.isNotWorking { + let client = clients.removeFirst() + teller.workingQueue.async { + teller.handleBusiness(for: client) + semaphore.signal() + } + self.finishedClientNumber += 1 + } + } + } + for _ in 0.. Int { + return Int.random(in: minNumber...maxNumber) +} + +private func initClients(_ number: Int) -> [Client]? { + var clients: [Client] = [] + + for waitingNumber in 1...number { + clients.append(Client(waitingNumber: waitingNumber)) + } + return clients +} + +private func main() { + let bank = Bank() + let tellerNumber = 3 + let maxClientNumber = 30 + let minClientNumber = 10 + var isContinue = true + + func initClients(_ number: Int) -> [Client] { + var clients: [Client] = [] + + for waitingNumber in 1...number { + clients.append(Client(waitingNumber: waitingNumber)) + } + return clients + } + + while isContinue { + Dashboard.printMenu() + + guard let input = readLine(), let command = Menu(rawValue: input) else { + print(BankError.wrongInput.description) + continue + } + + switch command { + case .start: + let clients = initClients(randomNumber(from: minClientNumber, to: maxClientNumber)) + bank.operateBank(teller: tellerNumber, client: clients) + case .end: + isContinue = false + } + } +} + +main()