//
//  VersionSeed.swift
//  OpenSwiftUICore
//
//  Audited for 6.0.87
//  Status: Complete

package struct VersionSeed: CustomStringConvertible {
    @inlinable
    package static var invalid: VersionSeed { VersionSeed(value: .max) }
    
    @inlinable
    package static var empty: VersionSeed { VersionSeed(value: .zero) }
    
    @inlinable
    package var isInvalid: Bool { value == VersionSeed.invalid.value }
    
    @inlinable
    package var isEmpty: Bool { value == VersionSeed.empty.value }
    
    var value: UInt32
    
    @inlinable
    package init(nodeId: UInt32, viewSeed: UInt32) {
        self.init(value: merge32(nodeId, viewSeed))
    }
    
    @inlinable
    package init(value: UInt32) {
        self.value = value
    }
    
    @inlinable
    package func matches(_ other: VersionSeed) -> Bool {
        !isInvalid && !other.isInvalid && value == other.value
    }
    
    package mutating func merge(_ other: VersionSeed) {
        guard !isInvalid, !other.isEmpty else {
            return
        }
        guard !isEmpty, !other.isInvalid else {
            self = other
            return
        }
        value = merge32(value, other.value)
    }
    
    package mutating func mergeValue(_ other: UInt32) {
        guard !isInvalid else { return }
        guard !isEmpty else {
            value = other
            return
        }
        value = merge32(value, other)
    }

    package var description: String {
        switch value {
        case VersionSeed.empty.value: "empty"
        case VersionSeed.invalid.value: "invalid"
        default: value.description
        }
    }
}

private func merge32(_ a: UInt32, _ b: UInt32) -> UInt32 {
    let a = UInt64(a)
    let b = UInt64(b)
    var c = b
    c &+= .max ^ (c &<< 32)
    c &+= a &<< 32
    c ^= (c &>> 22)
    c &+= .max ^ (c &<< 13)
    c ^= (c &>> 8)
    c &+= (c &<< 3)
    c ^= (c >> 15)
    c &+= .max ^ (c &<< 27)
    c ^= (c &>> 31)
    return UInt32(truncatingIfNeeded: c)
}
