import Metal
import MetalKit

public class Adamantium {
    public static var sharedDevice: MTLDevice?
    public static var sharedLibrary: MTLLibrary?
    public static var sharedCommandQueue: MTLCommandQueue?
    public static var sharedTextureLoader: MTKTextureLoader!
    
    public static func configure() {
        setupGlobals()
        deleteTemporaryFiles()
    }
    
    public static func setupGlobals() {
        
#if targetEnvironment(simulator)
        let libraryName = Adamantium.Constants.iOSSimulatorLibName
#else
        let libraryName = Adamantium.Constants.iOSLibName
#endif
        
        let libraryURL = Bundle.module.url(
            forResource: libraryName,
            withExtension: Adamantium.Constants.libraryExtension,
            subdirectory: Constants.metallibSubdirectory)
        
        guard
            let libraryURL,
            let device = MTLCreateSystemDefaultDevice() else {
            print("Adamantium Error: Could not setup shared device")
            return
        }
        sharedDevice = device
        sharedTextureLoader = MTKTextureLoader(device: device)
        
        guard let library = try? device.makeLibrary(URL: libraryURL) else {
            print("Adamantium Error: Could not setup library from bundle path")
            return
        }
        sharedLibrary = library
        
        guard let commandQueue = device.makeCommandQueue() else {
            print("Adamantium Error: Could not setup shared command queue")
            return
        }
        sharedCommandQueue = commandQueue
    }
    
    static let temporaryFilePrefix: String = "adamantium-temp-file-"
    
    static func deleteTemporaryFiles() {
        let fileManager = FileManager.default
        
        guard
            let documentsDirectory = fileManager
            .urls(for: .documentDirectory, in: .userDomainMask).first
        else { return }
        
        // Get the list of all files in the directory
        guard let files = try? fileManager.contentsOfDirectory(atPath: documentsDirectory.path) else { return }
        
        for file in files {
            // Check if the file starts with the given prefix
            if file.hasPrefix(temporaryFilePrefix) {
                let filePath = documentsDirectory.appendingPathComponent(file).path
                do {
                    try fileManager.removeItem(atPath: filePath)
                } catch {
                    print("Adamantium: Couldn't delete temporary file: \(filePath)")
                }
            }
        }
    }
    
    static func createRandomFileURLInDocuments(_ fileExtension: String) -> URL? {
        // Get the user's Documents directory
        guard
            let documentsDirectory = FileManager.default
            .urls(for: .documentDirectory, in: .userDomainMask).first
        else {
            print("Failed to find the Documents directory.")
            return nil
        }
        
        // Generate a random file name
        let randomFileName = Adamantium.temporaryFilePrefix
                           + UUID().uuidString + "." + fileExtension
        
        // Create the full file URL in the Documents directory
        let fileURL = documentsDirectory.appendingPathComponent(randomFileName)
        return fileURL
    }
}

public extension Adamantium {
    enum Constants {
        public static let metallibSubdirectory  = "Metal_Library"
        public static let iOSLibName            = "ios_adamantium"
        public static let macOSLibName          = "macos_adamanitum"
        public static let iOSSimulatorLibName   = "iossimulator_adamantium"
        public static let libraryExtension      = "metallib"
    }
}
