//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#if DEPLOYMENT_RUNTIME_SWIFT
    
func _NSIndexPathCreateFromIndexes(_ idx1: Int, _ idx2: Int) -> NSObject {
    var indexes = (idx1, idx2)
    return withUnsafeBytes(of: &indexes) { (ptr) -> NSIndexPath in
        return NSIndexPath.init(indexes: ptr.baseAddress!.assumingMemoryBound(to: Int.self), length: 2)
    }
}
    
#else
    
@_exported import Foundation // Clang module
import _SwiftFoundationOverlayShims
    
#endif

/**
 `IndexPath` represents the path to a specific node in a tree of nested array collections.
 
 Each index in an index path represents the index into an array of children from one node in the tree to another, deeper, node.
 */
public struct IndexPath : ReferenceConvertible, Equatable, Hashable, MutableCollection, RandomAccessCollection, Comparable, ExpressibleByArrayLiteral {
    public typealias ReferenceType = NSIndexPath
    public typealias Element = Int
    public typealias Index = Array<Int>.Index
    public typealias Indices = DefaultRandomAccessIndices<IndexPath>
    
    fileprivate enum Storage : ExpressibleByArrayLiteral {
        typealias Element = Int
        case empty
        case single(Int)
        case pair(Int, Int)
        case array([Int])
        
        init(arrayLiteral elements: Int...) {
            self.init(elements)
        }
        
        init(_ elements: [Int]) {
            switch elements.count {
            case 0:
                self = .empty
                break
            case 1:
                self = .single(elements[0])
                break
            case 2:
                self = .pair(elements[0], elements[1])
                break
            default:
                self = .array(elements)
                break
            }
        }
        
        func dropLast() -> Storage {
            switch self {
            case .empty:
                return .empty
            case .single(_):
                return .empty
            case .pair(let first, _):
                return .single(first)
            case .array(let indexes):
                switch indexes.count {
                case 3:
                    return .pair(indexes[0], indexes[1])
                default:
                    return .array(Array<Int>(indexes.dropLast()))
                }
            }
        }
        
        mutating func append(_ other: Int) {
            switch self {
            case .empty:
                self = .single(other)
                break
            case .single(let first):
                self = .pair(first, other)
                break
            case .pair(let first, let second):
                self = .array([first, second, other])
                break
            case .array(let indexes):
                self = .array(indexes + [other])
                break
            }
        }
        
        mutating func append(contentsOf other: Storage) {
            switch self {
            case .empty:
                switch other {
                case .empty:
                    // DO NOTHING
                    break
                case .single(let rhsIndex):
                    self = .single(rhsIndex)
                    break
                case .pair(let rhsFirst, let rhsSecond):
                    self = .pair(rhsFirst, rhsSecond)
                    break
                case .array(let rhsIndexes):
                    self = .array(rhsIndexes)
                    break
                }
                break
            case .single(let lhsIndex):
                switch other {
                case .empty:
                    // DO NOTHING
                    break
                case .single(let rhsIndex):
                    self = .pair(lhsIndex, rhsIndex)
                    break
                case .pair(let rhsFirst, let rhsSecond):
                    self = .array([lhsIndex, rhsFirst, rhsSecond])
                    break
                case .array(let rhsIndexes):
                    self = .array([lhsIndex] + rhsIndexes)
                    break
                }
                break
            case .pair(let lhsFirst, let lhsSecond):
                switch other {
                case .empty:
                    // DO NOTHING
                    break
                case .single(let rhsIndex):
                    self = .array([lhsFirst, lhsSecond, rhsIndex])
                    break
                case .pair(let rhsFirst, let rhsSecond):
                    self = .array([lhsFirst, lhsSecond, rhsFirst, rhsSecond])
                    break
                case .array(let rhsIndexes):
                    self = .array([lhsFirst, lhsSecond] + rhsIndexes)
                    break
                }
                break
            case .array(let lhsIndexes):
                switch other {
                case .empty:
                    // DO NOTHING
                    break
                case .single(let rhsIndex):
                    self = .array(lhsIndexes + [rhsIndex])
                    break
                case .pair(let rhsFirst, let rhsSecond):
                    self = .array(lhsIndexes + [rhsFirst, rhsSecond])
                    break
                case .array(let rhsIndexes):
                    self = .array(lhsIndexes + rhsIndexes)
                    break
                }
                break
            }
        }
        
        mutating func append(contentsOf other: [Int]) {
            switch self {
            case .empty:
                switch other.count {
                case 0:
                    // DO NOTHING
                    break
                case 1:
                    self = .single(other[0])
                    break
                case 2:
                    self = .pair(other[0], other[1])
                    break
                default:
                    self = .array(other)
                    break
                }
                break
            case .single(let first):
                switch other.count {
                case 0:
                    // DO NOTHING
                    break
                case 1:
                    self = .pair(first, other[0])
                    break
                default:
                    self = .array([first] + other)
                    break
                }
                break
            case .pair(let first, let second):
                switch other.count {
                case 0:
                    // DO NOTHING
                    break
                default:
                    self = .array([first, second] + other)
                    break
                }
                break
            case .array(let indexes):
                self = .array(indexes + other)
                break
            }
        }
        
        subscript(_ index: Int) -> Int {
            get {
                switch self {
                case .empty:
                    fatalError("index \(index) out of bounds of count 0")
                    break
                case .single(let first):
                    precondition(index == 0, "index \(index) out of bounds of count 1")
                    return first
                case .pair(let first, let second):
                    precondition(index >= 0 && index < 2, "index \(index) out of bounds of count 2")
                    return index == 0 ? first : second
                case .array(let indexes):
                    return indexes[index]
                }
            }
            set {
                switch self {
                case .empty:
                    fatalError("index \(index) out of bounds of count 0")
                    break
                case .single(_):
                    precondition(index == 0, "index \(index) out of bounds of count 1")
                    self = .single(newValue)
                    break
                case .pair(let first, let second):
                    precondition(index >= 0 && index < 2, "index \(index) out of bounds of count 2")
                    if index == 0 {
                        self = .pair(newValue, second)
                    } else {
                        self = .pair(first, newValue)
                    }
                    break
                case .array(let indexes_):
                    var indexes = indexes_
                    indexes[index] = newValue
                    self = .array(indexes)
                    break
                }
            }
        }
        
        subscript(range: Range<Index>) -> Storage {
            get {
                switch self {
                case .empty:
                    switch (range.lowerBound, range.upperBound) {
                    case (0, 0):
                        return .empty
                    default:
                        fatalError("range \(range) is out of bounds of count 0")
                    }
                case .single(let index):
                    switch (range.lowerBound, range.upperBound) {
                    case (0, 0): fallthrough
                    case (1, 1):
                        return .empty
                    case (0, 1):
                        return .single(index)
                    default:
                        fatalError("range \(range) is out of bounds of count 1")
                    }
                    return self
                case .pair(let first, let second):
                    
                    switch (range.lowerBound, range.upperBound) {
                    case (0, 0):
                        fallthrough
                    case (1, 1):
                        fallthrough
                    case (2, 2):
                        return .empty
                    case (0, 1):
                        return .single(first)
                    case (1, 2):
                        return .single(second)
                    case (0, 2):
                        return self
                    default:
                        fatalError("range \(range) is out of bounds of count 2")
                    }
                case .array(let indexes):
                    let slice = indexes[range]
                    switch slice.count {
                    case 0:
                        return .empty
                    case 1:
                        return .single(slice[0])
                    case 2:
                        return .pair(slice[0], slice[1])
                    default:
                        return .array(Array<Int>(slice))
                    }
                }
            }
            set {
                switch self {
                case .empty:
                    precondition(range.lowerBound == 0 && range.upperBound == 0, "range \(range) is out of bounds of count 0")
                    self = newValue
                    break
                case .single(let index):
                    switch (range.lowerBound, range.upperBound, newValue) {
                    case (0, 0, .empty):
                        fallthrough
                    case (1, 1, .empty):
                        break
                    case (0, 0, .single(let other)):
                        self = .pair(other, index)
                        break
                    case (0, 0, .pair(let first, let second)):
                        self = .array([first, second, index])
                        break
                    case (0, 0, .array(let other)):
                        self = .array(other + [index])
                        break
                    case (0, 1, .empty):
                        fallthrough
                    case (0, 1, .single):
                        fallthrough
                    case (0, 1, .pair):
                        fallthrough
                    case (0, 1, .array):
                        self = newValue
                    case (1, 1, .single(let other)):
                        self = .pair(index, other)
                        break
                    case (1, 1, .pair(let first, let second)):
                        self = .array([index, first, second])
                        break
                    case (1, 1, .array(let other)):
                        self = .array([index] + other)
                        break
                    default:
                        fatalError("range \(range) is out of bounds of count 1")
                    }
                case .pair(let first, let second):
                    switch (range.lowerBound, range.upperBound) {
                    case (0, 0):
                        switch newValue {
                        case .empty:
                            break
                        case .single(let other):
                            self = .array([other, first, second])
                            break
                        case .pair(let otherFirst, let otherSecond):
                            self = .array([otherFirst, otherSecond, first, second])
                            break
                        case .array(let other):
                            self = .array(other + [first, second])
                            break
                        }
                        break
                    case (0, 1):
                        switch newValue {
                        case .empty:
                            self = .single(second)
                            break
                        case .single(let other):
                            self = .pair(other, second)
                            break
                        case .pair(let otherFirst, let otherSecond):
                            self = .array([otherFirst, otherSecond, second])
                            break
                        case .array(let other):
                            self = .array(other + [second])
                            break
                        }
                        break
                    case (0, 2):
                        self = newValue
                        break
                    case (1, 2):
                        switch newValue {
                        case .empty:
                            self = .single(first)
                            break
                        case .single(let other):
                            self = .pair(first, other)
                            break
                        case .pair(let otherFirst, let otherSecond):
                            self = .array([first, otherFirst, otherSecond])
                            break
                        case .array(let other):
                            self = .array([first] + other)
                        }
                        break
                    case (2, 2):
                        switch newValue {
                        case .empty:
                            break
                        case .single(let other):
                            self = .array([first, second, other])
                            break
                        case .pair(let otherFirst, let otherSecond):
                            self = .array([first, second, otherFirst, otherSecond])
                            break
                        case .array(let other):
                            self = .array([first, second] + other)
                        }
                        break
                    default:
                        fatalError("range \(range) is out of bounds of count 2")
                    }
                case .array(let indexes):
                    var newIndexes = indexes
                    newIndexes.removeSubrange(range)
                    switch newValue {
                    case .empty:
                        break
                    case .single(let index):
                        newIndexes.insert(index, at: range.lowerBound)
                        break
                    case .pair(let first, let second):
                        newIndexes.insert(first, at: range.lowerBound)
                        newIndexes.insert(second, at: range.lowerBound + 1)
                        break
                    case .array(let other):
                        newIndexes.insert(contentsOf: other, at: range.lowerBound)
                        break
                    }
                    self = Storage(newIndexes)
                    break
                }
            }
        }
        
        var count: Int {
            switch self {
            case .empty:
                return 0
            case .single:
                return 1
            case .pair:
                return 2
            case .array(let indexes):
                return indexes.count
            }
        }
        
        var startIndex: Int {
            return 0
        }
        
        var endIndex: Int {
            return count
        }
        
        var allValues: [Int] {
            switch self {
            case .empty: return []
            case .single(let index): return [index]
            case .pair(let first, let second): return [first, second]
            case .array(let indexes): return indexes
            }
        }
        
        func index(before i: Int) -> Int {
            return i - 1
        }
        
        func index(after i: Int) -> Int {
            return i + 1
        }
        
        var description: String {
            switch self {
            case .empty:
                return "[]"
            case .single(let index):
                return "[\(index)]"
            case .pair(let first, let second):
                return "[\(first), \(second)]"
            case .array(let indexes):
                return indexes.description
            }
        }
        
        func withUnsafeBufferPointer<R>(_ body: (UnsafeBufferPointer<Int>) throws -> R) rethrows -> R {
            switch self {
            case .empty:
                return try body(UnsafeBufferPointer<Int>(start: nil, count: 0))
            case .single(let index_):
                var index = index_
                return try withUnsafePointer(to: &index) { (start) throws -> R in
                    return try body(UnsafeBufferPointer<Int>(start: start, count: 1))
                }
            case .pair(let first, let second):
                var pair = (first, second)
                return try withUnsafeBytes(of: &pair) { (rawBuffer: UnsafeRawBufferPointer) throws -> R in
                    return try body(UnsafeBufferPointer<Int>(start: rawBuffer.baseAddress?.assumingMemoryBound(to: Int.self), count: 2))
                }
            case .array(let indexes):
                return try indexes.withUnsafeBufferPointer(body)
            }
        }
        
        var debugDescription: String { return description }
        
        static func +(_ lhs: Storage, _ rhs: Storage) -> Storage {
            var res = lhs
            res.append(contentsOf: rhs)
            return res
        }
        
        static func +(_ lhs: Storage, _ rhs: [Int]) -> Storage {
            var res = lhs
            res.append(contentsOf: rhs)
            return res
        }
        
        static func ==(_ lhs: Storage, _ rhs: Storage) -> Bool {
            switch (lhs, rhs) {
            case (.empty, .empty):
                return true
            case (.single(let lhsIndex), .single(let rhsIndex)):
                return lhsIndex == rhsIndex
            case (.pair(let lhsFirst, let lhsSecond), .pair(let rhsFirst, let rhsSecond)):
                return lhsFirst == rhsFirst && lhsSecond == rhsSecond
            case (.array(let lhsIndexes), .array(let rhsIndexes)):
                return lhsIndexes == rhsIndexes
            default:
                return false
            }
        }
    }
    
    fileprivate var _indexes : Storage
    
    /// Initialize an empty index path.
    public init() {
        _indexes = []
    }
    
    /// Initialize with a sequence of integers.
    public init<ElementSequence : Sequence>(indexes: ElementSequence)
        where ElementSequence.Iterator.Element == Element {
            _indexes = Storage(indexes.map { $0 })
    }
    
    /// Initialize with an array literal.
    public init(arrayLiteral indexes: Element...) {
        _indexes = Storage(indexes)
    }
    
    /// Initialize with an array of elements.
    public init(indexes: Array<Element>) {
        _indexes = Storage(indexes)
    }
    
    fileprivate init(storage: Storage) {
        _indexes = storage
    }
    
    /// Initialize with a single element.
    public init(index: Element) {
        _indexes = [index]
    }
    
    /// Return a new `IndexPath` containing all but the last element.
    public func dropLast() -> IndexPath {
        return IndexPath(storage: _indexes.dropLast())
    }
    
    /// Append an `IndexPath` to `self`.
    public mutating func append(_ other: IndexPath) {
        _indexes.append(contentsOf: other._indexes)
    }
    
    /// Append a single element to `self`.
    public mutating func append(_ other: Element) {
        _indexes.append(other)
    }
    
    /// Append an array of elements to `self`.
    public mutating func append(_ other: Array<Element>) {
        _indexes.append(contentsOf: other)
    }
    
    /// Return a new `IndexPath` containing the elements in self and the elements in `other`.
    public func appending(_ other: Element) -> IndexPath {
        var result = _indexes
        result.append(other)
        return IndexPath(storage: result)
    }
    
    /// Return a new `IndexPath` containing the elements in self and the elements in `other`.
    public func appending(_ other: IndexPath) -> IndexPath {
        return IndexPath(storage: _indexes + other._indexes)
    }
    
    /// Return a new `IndexPath` containing the elements in self and the elements in `other`.
    public func appending(_ other: Array<Element>) -> IndexPath {
        return IndexPath(storage: _indexes + other)
    }
    
    public subscript(index: Index) -> Element {
        get {
            return _indexes[index]
        }
        set {
            _indexes[index] = newValue
        }
    }
    
    public subscript(range: Range<Index>) -> IndexPath {
        get {
            return IndexPath(storage: _indexes[range])
        }
        set {
            _indexes[range] = newValue._indexes
        }
    }
    
    public func makeIterator() -> IndexingIterator<IndexPath> {
        return IndexingIterator(_elements: self)
    }
    
    public var count: Int {
        return _indexes.count
    }
    
    public var startIndex: Index {
        return _indexes.startIndex
    }
    
    public var endIndex: Index {
        return _indexes.endIndex
    }
    
    public func index(before i: Index) -> Index {
        return _indexes.index(before: i)
    }
    
    public func index(after i: Index) -> Index {
        return _indexes.index(after: i)
    }
    
    /// Sorting an array of `IndexPath` using this comparison results in an array representing nodes in depth-first traversal order.
    public func compare(_ other: IndexPath) -> ComparisonResult  {
        let thisLength = count
        let otherLength = other.count
        let length = Swift.min(thisLength, otherLength)
        for idx in 0..<length {
            let otherValue = other[idx]
            let value = self[idx]
            if value < otherValue {
                return .orderedAscending
            } else if value > otherValue {
                return .orderedDescending
            }
        }
        if thisLength > otherLength {
            return .orderedDescending
        } else if thisLength < otherLength {
            return .orderedAscending
        }
        return .orderedSame
    }
    
    public var hashValue: Int {
        func hashIndexes(first: Int, last: Int, count: Int) -> Int {
            let totalBits = MemoryLayout<Int>.size * 8
            let lengthBits = 8
            let firstIndexBits = (totalBits - lengthBits) / 2
            return count &+ (first << lengthBits) &+ (last << (lengthBits + firstIndexBits))
        }
        
        switch _indexes {
            case .empty: return 0
            case .single(let index): return index.hashValue
            case .pair(let first, let second):
                return hashIndexes(first: first, last: second, count: 2)
            default:
                let cnt = _indexes.count
                return hashIndexes(first: _indexes[0], last: _indexes[cnt - 1], count: cnt)
        }
    }
    
    // MARK: - Bridging Helpers
    
    fileprivate init(nsIndexPath: ReferenceType) {
        let count = nsIndexPath.length
        if count == 0 {
            _indexes = []
        } else if count == 1 {
            _indexes = .single(nsIndexPath.index(atPosition: 0))
        } else if count == 2 {
            _indexes = .pair(nsIndexPath.index(atPosition: 0), nsIndexPath.index(atPosition: 1))
        } else {
            var indexes = Array<Int>(repeating: 0, count: count)
            indexes.withUnsafeMutableBufferPointer { (buffer: inout UnsafeMutableBufferPointer<Int>) -> Void in
                nsIndexPath.getIndexes(buffer.baseAddress!, range: NSRange(location: 0, length: count))
            }
            _indexes = .array(indexes)
        }
    }
    
    fileprivate func makeReference() -> ReferenceType {
        switch _indexes {
        case .empty:
            return ReferenceType()
        case .single(let index):
            return ReferenceType(index: index)
        case .pair(let first, let second):
            return _NSIndexPathCreateFromIndexes(first, second) as! ReferenceType
        default:
            return _indexes.withUnsafeBufferPointer {
                return ReferenceType(indexes: $0.baseAddress, length: $0.count)
            }
        }
    }
    
    public static func ==(lhs: IndexPath, rhs: IndexPath) -> Bool {
        return lhs._indexes == rhs._indexes
    }
    
    public static func +(lhs: IndexPath, rhs: IndexPath) -> IndexPath {
        return lhs.appending(rhs)
    }
    
    public static func +=(lhs: inout IndexPath, rhs: IndexPath) {
        lhs.append(rhs)
    }
    
    public static func <(lhs: IndexPath, rhs: IndexPath) -> Bool {
        return lhs.compare(rhs) == ComparisonResult.orderedAscending
    }
    
    public static func <=(lhs: IndexPath, rhs: IndexPath) -> Bool {
        let order = lhs.compare(rhs)
        return order == ComparisonResult.orderedAscending || order == ComparisonResult.orderedSame
    }
    
    public static func >(lhs: IndexPath, rhs: IndexPath) -> Bool {
        return lhs.compare(rhs) == ComparisonResult.orderedDescending
    }
    
    public static func >=(lhs: IndexPath, rhs: IndexPath) -> Bool {
        let order = lhs.compare(rhs)
        return order == ComparisonResult.orderedDescending || order == ComparisonResult.orderedSame
    }
}

extension IndexPath : CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
    public var description: String {
        return _indexes.description
    }
    
    public var debugDescription: String {
        return _indexes.debugDescription
    }
    
    public var customMirror: Mirror {
        return Mirror(self, unlabeledChildren: self, displayStyle: .collection)
    }
}

#if DEPLOYMENT_RUNTIME_SWIFT
internal typealias IndexPathBridgeType = _ObjectTypeBridgeable
#else
internal typealias IndexPathBridgeType = _ObjectiveCBridgeable
#endif

extension IndexPath : IndexPathBridgeType {
    public static func _getObjectiveCType() -> Any.Type {
        return NSIndexPath.self
    }
    
    @_semantics("convertToObjectiveC")
    public func _bridgeToObjectiveC() -> NSIndexPath {
        return makeReference()
    }
    
    public static func _forceBridgeFromObjectiveC(_ x: NSIndexPath, result: inout IndexPath?) {
        result = IndexPath(nsIndexPath: x)
    }
    
    public static func _conditionallyBridgeFromObjectiveC(_ x: NSIndexPath, result: inout IndexPath?) -> Bool {
        result = IndexPath(nsIndexPath: x)
        return true
    }
    
    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSIndexPath?) -> IndexPath {
        guard let src = source else { return IndexPath() }
        return IndexPath(nsIndexPath: src)
    }
}

extension NSIndexPath : _HasCustomAnyHashableRepresentation {
    // Must be @nonobjc to avoid infinite recursion during bridging.
    @nonobjc
    public func _toCustomAnyHashable() -> AnyHashable? {
        return AnyHashable(IndexPath(nsIndexPath: self))
    }
}

extension IndexPath : Codable {
    private enum CodingKeys : Int, CodingKey {
        case indexes
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        var indexesContainer = try container.nestedUnkeyedContainer(forKey: .indexes)
        
        var indexes = [Int]()
        if let count = indexesContainer.count {
            indexes.reserveCapacity(count)
        }
        
        while !indexesContainer.isAtEnd {
            let index = try indexesContainer.decode(Int.self)
            indexes.append(index)
        }
        
        self.init(indexes: indexes)
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        var indexesContainer = container.nestedUnkeyedContainer(forKey: .indexes)
        switch self._indexes {
        case .empty:
            break
        case .single(let index):
            try indexesContainer.encode(index)
        case .pair(let first, let second):
            try indexesContainer.encode(first)
            try indexesContainer.encode(second)
        case .array(let indexes):
            try indexesContainer.encode(contentsOf: indexes)
        }
    }
}
