 import Foundation
 
 extension FileManager {
-    /// Returns the first URL for the specified common directory in the user domain.
-    open func url(for directory: SearchPathDirectory) -> URL? {
-        urls(for: directory, in: .userDomainMask).first
-    }
-}
+    public struct CreationOptions {
+        public let resourceValue: URLResourceValues?
+        public let attributes: [FileAttributeKey: Any]?
 
-extension FileManager {
-    public enum Options {
-        case none
-        /// An option to create url if it does not already exist.
-        case createIfNotExists(_ resourceValue: URLResourceValues?)
+        public init(resourceValue: URLResourceValues?, attributes: [FileAttributeKey: Any]? = nil) {
+            self.resourceValue = resourceValue
+            self.attributes = attributes
+        }
 
-        public static var createIfNotExists: Self {
-            createIfNotExists(nil)
+        public static var none: Self {
+            .init(resourceValue: nil, attributes: nil)
         }
-    }
 
-    enum Error: Swift.Error {
-        case relativeDirectoryNotFound
-        case pathNotFound
-        case onlyDirectoryCreationSupported
+        /// Excluded from iCloud Backup with `nil` attributes.
+        public static var excludedFromBackup: Self {
+            // Exclude from iCloud Backup
+            var resourceValue = URLResourceValues()
+            resourceValue.isExcludedFromBackup = true
+            return .init(resourceValue: resourceValue)
+        }
+
+        /// Excluded from iCloud Backup with file protection of type `.complete`.
+        ///
+        /// The file is stored in an encrypted format on disk and cannot be read from or
+        /// written to while the device is locked or booting.
+        public static var secure: Self {
+            // Exclude from iCloud Backup
+            var resourceValue = URLResourceValues()
+            resourceValue.isExcludedFromBackup = true
+
+            return .init(
+                resourceValue: resourceValue,
+                attributes: [.protectionKey: FileProtectionType.complete]
+            )
+        }
     }
 
     /// Returns a `URL` constructed by appending the given path component relative

    open func appending(
        path: String,
        relativeTo directory: SearchPathDirectory,
        options: Options = .none
    ) throws -> URL {
        guard var directoryUrl = url(for: directory) else {
            throw Error.relativeDirectoryNotFound
        }

        directoryUrl = directoryUrl.appendingPathComponent(path, isDirectory: true)

        if case let .createIfNotExists(resourceValue) = options {
            try createIfNotExists(directoryUrl, resourceValue: resourceValue)
        }

        if fileExists(atPath: directoryUrl.path) {
            return directoryUrl
        }

        throw Error.pathNotFound
    }
}

extension FileManager {
    /// Creates the given url if it does not already exist.
    open func createIfNotExists(_ url: URL, resourceValue: URLResourceValues? = nil) throws {
        guard !fileExists(atPath: url.path) else {
            return
        }

        guard url.hasDirectoryPath else {
            throw Error.onlyDirectoryCreationSupported
        }

        var url = url
        try createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)

        if let resourceValue = resourceValue {
            try url.setResourceValues(resourceValue)
        }
    }
}

extension FileManager {
    /// Remove all cached data from `cachesDirectory`.
    public func removeAllCache() throws {
        try urls(for: .cachesDirectory, in: .userDomainMask).forEach { directory in


extension FileManager {
    var xcoreCacheDirectory: URL? {
        try? appending(
            path: "com.xcore",
            relativeTo: .cachesDirectory,
            options: .secure
        )
    }
}
