import Foundation
import PathKit
import XcodeProj

extension PBXFileElement {
    public var nameOrPath: String {
        return name ?? path ?? ""
    }

    static func sortByNamePath(_ lhs: PBXFileElement, _ rhs: PBXFileElement) -> Bool {
        return lhs.namePathSortString.localizedStandardCompare(rhs.namePathSortString) == .orderedAscending
    }

    private var namePathSortString: String {
        // This string needs to be unique for all combinations of name & path or the order won't be stable.
        return "\(name ?? path ?? "")\t\(name ?? "")\t\(path ?? "")"
    }
}

extension PBXProj {

    public func printGroups() -> String {
        guard let project = projects.first,
            let mainGroup = project.mainGroup else {
            return ""
        }
        return printGroup(group: mainGroup)
    }

    public func printGroup(group: PBXGroup) -> String {
        var string = group.nameOrPath
        for child in group.children {
            if let group = child as? PBXGroup {
                string += "\n 📁 " + printGroup(group: group).replacingOccurrences(of: "\n ", with: "\n    ")
            } else if let fileReference = child as? PBXFileReference {
                string += "\n 📄 " + fileReference.nameOrPath
            } else if let variantGroup = child as? PBXVariantGroup {
                string += "\n 🌎 " + variantGroup.nameOrPath
            } else if let versionGroup = child as? XCVersionGroup {
                string += "\n 🔢 " + versionGroup.nameOrPath
            } else if let syncedFolder = child as? PBXFileSystemSynchronizedRootGroup {
                string += "\n 📁 " + syncedFolder.nameOrPath
            }
        }
        return string
    }
}

extension Dictionary {

    public var valueArray: [Value] {
        Array(values)
    }
}

extension Xcode {

    public static func fileType(path: Path, productType: PBXProductType? = nil) -> String? {
        guard let fileExtension = path.extension else { return nil }
        switch (fileExtension, productType) {
        // cases that aren't handled (yet) in XcodeProj.
        case ("appex", .extensionKitExtension):
            return "wrapper.extensionkit-extension"
        case ("swiftcrossimport", _):
            return "wrapper.swiftcrossimport"
        case ("xcstrings", _):
            return "text.json.xcstrings"
        case ("icon", _):
            return "wrapper.icon"
        default:
            // fallback to XcodeProj defaults
            return Xcode.filetype(extension: fileExtension)
        }
    }

    public static func isDirectoryFileWrapper(path: Path) -> Bool {
        guard path.isDirectory else { return false }
        return fileType(path: path) != nil
    }
}
