//
// Copyright © 2023 Nevis Security AG. All rights reserved.
//

import Foundation

class OperationCache {
	static let shared = OperationCache()

	// MARK: Properties

	private var cache: [String: Operation] = [:]

	// MARK: Initialization

	private init() {}

	// MARK: Public Interface

	@discardableResult
	func put(_ operation: Operation, using id: String) -> Operation {
		cache[id] = operation
		return operation
	}

	func read<T>(by id: String) -> T {
		validate(id: id)

		guard let operation = cache[id] else {
			fatalError("Operation is missing!")
		}

		return validate(operation: operation)
	}

	func update(by id: String, operation: Operation) {
		cache[id] = operation
	}

	func delete(by id: String) {
		cache.removeValue(forKey: id)
	}

	func cancel(by id: String) {
		cache[id]?.cancel()
	}
}

// MARK: Private Interface

private extension OperationCache {
	func validate(id: String) {
		if id.trimmingCharacters(in: .whitespaces).isEmpty {
			fatalError("Operation identifier is missing!")
		}
	}

	func validate<T>(operation: Operation) -> T {
		guard type(of: operation) is T.Type else {
			fatalError("Wrong type of operation found!")
		}

		return operation as! T
	}
}
