import Foundation

/// Safe resolver for CodexBarCore's SwiftPM resource bundle.
///
/// The autogenerated `Bundle.module` accessor traps at launch when the packaged
/// app does not place `CodexBar_CodexBarCore.bundle` at the locations it probes
/// (the app root and the compile-time build directory). The packaged app ships
/// the bundle in `Contents/Resources`, so resolve through the main bundle first
/// and only touch `Bundle.module` after verifying that its development-build
/// candidate exists. Shipped command-line tools resolve the bundle beside the
/// executable; a missing bundle is reported by callers instead of trapping.
public enum CodexBarCoreResources {
    static let missingBundleMessage =
        "CodexBarCore resource bundle is missing next to the executable; reinstall or update CodexBar"

    public static let bundle: Bundle? = resolve(mainBundle: .main)

    static func resolve(
        mainBundle: Bundle,
        executableBundleURL: URL? = nil,
        swiftPMBuildDirectory: URL? = Self.defaultSwiftPMBuildDirectory) -> Bundle?
    {
        let name = "CodexBar_CodexBarCore"
        let bundleName = "\(name).bundle"
        let swiftPMBundleNames = [bundleName, "\(name).resources"]

        if mainBundle.bundleURL.pathExtension == "app" {
            if let url = mainBundle.url(forResource: name, withExtension: "bundle"),
               let bundle = Bundle(url: url)
            {
                return bundle
            }
            if let resourceURL = mainBundle.resourceURL,
               let bundle = Bundle(url: resourceURL.appendingPathComponent(bundleName))
            {
                return bundle
            }
            if let bundle = Bundle(url: mainBundle.bundleURL.appendingPathComponent(bundleName)) {
                return bundle
            }
        }

        let executableDirectory = executableBundleURL ?? mainBundle.bundleURL
        for swiftPMBundleName in swiftPMBundleNames {
            let executableCandidate = executableDirectory.appendingPathComponent(swiftPMBundleName)
            if let bundle = Bundle(url: executableCandidate) {
                return bundle
            }
        }

        if let swiftPMBuildDirectory {
            let buildCandidateExists = swiftPMBundleNames.contains { buildBundleName in
                var isDirectory: ObjCBool = false
                let buildCandidate = swiftPMBuildDirectory.appendingPathComponent(buildBundleName)
                return FileManager.default.fileExists(atPath: buildCandidate.path, isDirectory: &isDirectory)
                    && isDirectory.boolValue
            }
            if buildCandidateExists {
                return .module
            }
        }
        return nil
    }

    private static let defaultSwiftPMBuildDirectory: URL = {
        let packageRoot = URL(fileURLWithPath: #filePath)
            .deletingLastPathComponent() // CodexBarCore
            .deletingLastPathComponent() // Sources
            .deletingLastPathComponent() // package root
        #if DEBUG
        let configuration = "debug"
        #else
        let configuration = "release"
        #endif
        return packageRoot.appendingPathComponent(".build/\(configuration)", isDirectory: true)
    }()
}
