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"
    }
}
