import Foundation enum TrainingError: Error { case invalidGetResponseData(Int) case invalidResponse(URL, Int) case missingArguments(String) case configurationFileMissing(URL) case configurationFileUnreadable(URL, Error) case configurationFileDecodingFailed(URL, Error) case invalidServerPath(String) case mainImageFolderNotCreated(Error) case failedToRemoveSessionFolder(Error) case failedToGetCapDatabase(Error) case failedToDecodeCapDatabase(Error) case failedToLoadImage(CapImage, Error) case failedToCreateImageFolder(Int, Error) case invalidImageRequestResponse(CapImage, Int) case failedToSaveImage(CapImage, Error) case failedToLoadImages(expected: Int, loaded: Int) case failedToGetChangedImagesList(Error) case invalidEntryInChangeList(String) case failedToGetListOfImageFolders(Error) case failedToRemoveImageFolder(String, Error) case failedToGetClassifierVersion(Error) case invalidClassifierVersion(String) case failedToCreateClassifier(Error) case failedToWriteClassifier(Error) case failedToReadClassifierData(Error) case failedToUploadClassifier(Error) case failedToUploadClassifierClasses(Error) case magickDependencyCheckFailed(Error) case magickDependencyNotFound case failedToCreateThumbnailFolder(Error) case failedToGetMissingThumbnailIds(Error) case missingMainImage(Int) case failedToCreateThumbnail(Int, String) case failedToReadCreatedThumbnail(Int, Error) case failedToUploadCreatedThumbnail(Int, Error) } extension TrainingError: CustomStringConvertible { var description: String { switch self { case .missingArguments(let argument): return "Missing argument '\(argument)'" case .configurationFileMissing(let url): return "No configuration at \(url.absoluteURL.path)" case .configurationFileUnreadable(let url, let error): return "Failed to load configuration data at \(url.absoluteURL.path): \(error)" case .configurationFileDecodingFailed(let url, let error): return "Failed to decode configuration at \(url.absoluteURL.path): \(error)" case .invalidServerPath(let path): return "Configuration: Invalid server path \(path)" case .mainImageFolderNotCreated(let error): return "Failed to create main image folder: \(error)" case .failedToRemoveSessionFolder(let error): return "Failed to remove session folder: \(error)" case .failedToGetCapDatabase(let error): return "Failed to get cap database from server: \(error)" case .failedToDecodeCapDatabase(let error): return "Failed to decode cap database: \(error)" case .failedToGetListOfImageFolders(let error): return "Failed to get list of image folders: \(error)" case .failedToRemoveImageFolder(let folder, let error): return "Failed to delete unused image folder \(folder): \(error)" case .failedToCreateImageFolder(let cap, let error): return "Failed to create image folder for cap \(cap): \(error)" case .failedToLoadImage(let image, let error): return "Failed to load \(image): \(error)" case .invalidImageRequestResponse(let image, let responseCode): return "Failed to load \(image): Response \(responseCode)" case .failedToSaveImage(let image, let error): return "Failed to save \(image): \(error)" case .failedToLoadImages(let expected, let loaded): return "Only \(loaded) of \(expected) images loaded" case .failedToGetChangedImagesList(let error): return "Failed to get list of changed images: \(error)" case .invalidEntryInChangeList(let entry): return "Invalid change list entry: '\(entry)'" case .failedToGetClassifierVersion(let error): return "Failed to get classifier version: \(error)" case .invalidClassifierVersion(let string): return "Invalid classifier version \(string)" case .failedToCreateClassifier(let error): return "Failed to create classifier: \(error)" case .failedToWriteClassifier(let error): return "Failed to save model to file: \(error)" case .failedToReadClassifierData(let error): return "Failed to read classifier data: \(error)" case .failedToUploadClassifier(let error): return "Failed to upload classifier: \(error)" case .failedToUploadClassifierClasses(let error): return "Failed to upload classifier classes: \(error)" case .magickDependencyCheckFailed(let error): return "Failed to get version of magick: (\(error))" case .magickDependencyNotFound: return "Magick not found, install using 'brew install imagemagick'" case .failedToCreateThumbnailFolder(let error): return "Failed to create folder for thumbnails: \(error)" case .failedToGetMissingThumbnailIds(let error): return "Failed to get missing thumbnails ids: \(error)" case .missingMainImage(let cap): return "Local main image not found for cap \(cap)" case .failedToCreateThumbnail(let cap, let message): return "Failed to read created thumbnail for cap \(cap): \(message)" case .failedToReadCreatedThumbnail(let cap, let error): return "Failed to read created thumbnail for cap \(cap): \(error)" case .failedToUploadCreatedThumbnail(let cap, let error): return "Failed to upload thumbnail for cap \(cap): \(error)" case .invalidGetResponseData(let count): return "Response (\(count) bytes) is not a valid string" case .invalidResponse(let url, let code): return "Invalid response \(code) to \(url.absoluteString)" } } }