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

#if DEPLOYMENT_RUNTIME_SWIFT

import CoreFoundation

public struct _NSRange {
    public var location: Int
    public var length: Int
    
    
    public init() {
        location = 0
        length = 0
    }
    
    public init(location: Int, length: Int) {
        self.location = location
        self.length = length
    }
}
    
public typealias NSRange = _NSRange
    
public typealias NSRangePointer = UnsafeMutablePointer<NSRange>

public func NSMakeRange(_ loc: Int, _ len: Int) -> NSRange {
    return NSRange(location: loc, length: len)
}

public func NSMaxRange(_ range: NSRange) -> Int {
    return range.location + range.length
}

public func NSLocationInRange(_ loc: Int, _ range: NSRange) -> Bool {
    return !(loc < range.location) && (loc - range.location) < range.length
}

public func NSEqualRanges(_ range1: NSRange, _ range2: NSRange) -> Bool {
    return range1.location == range2.location && range1.length == range2.length
}

public func NSUnionRange(_ range1: NSRange, _ range2: NSRange) -> NSRange {
    let max1 = range1.location + range1.length
    let max2 = range2.location + range2.length
    let maxend: Int
    if max1 > max2 {
        maxend = max1
    } else {
        maxend = max2
    }
    let minloc: Int
    if range1.location < range2.location {
        minloc = range1.location
    } else {
        minloc = range2.location
    }
    return NSMakeRange(minloc, maxend - minloc)
}

public func NSIntersectionRange(_ range1: NSRange, _ range2: NSRange) -> NSRange {
    let max1 = range1.location + range1.length
    let max2 = range2.location + range2.length
    let minend: Int
    if max1 < max2 {
        minend = max1
    } else {
        minend = max2
    }
    if range2.location <= range1.location && range1.location < max2 {
        return NSMakeRange(range1.location, minend - range1.location)
    } else if range1.location <= range2.location && range2.location < max1 {
        return NSMakeRange(range2.location, minend - range2.location)
    }
    return NSMakeRange(0, 0)
}

public func NSStringFromRange(_ range: NSRange) -> String {
    return "{\(range.location), \(range.length)}"
}

public func NSRangeFromString(_ aString: String) -> NSRange {
    let emptyRange = NSMakeRange(0, 0)
    if aString.isEmpty {
        // fail early if the string is empty
        return emptyRange
    }
    let scanner = Scanner(string: aString)
    let digitSet = CharacterSet.decimalDigits
    let _ = scanner.scanUpToCharactersFromSet(digitSet)
    if scanner.isAtEnd {
        // fail early if there are no decimal digits
        return emptyRange
    }
    guard let location = scanner.scanInt() else {
        return emptyRange
    }
    let partialRange = NSMakeRange(location, 0)
    if scanner.isAtEnd {
        // return early if there are no more characters after the first int in the string
        return partialRange
    }
    let _ = scanner.scanUpToCharactersFromSet(digitSet)
    if scanner.isAtEnd {
        // return early if there are no integer characters after the first int in the string
        return partialRange
    }
    guard let length = scanner.scanInt() else {
        return partialRange
    }
    return NSMakeRange(location, length)
}
    
#else
@_exported import Foundation // Clang module
#endif

extension NSRange : Hashable {
    public var hashValue: Int {
        #if arch(i386) || arch(arm)
            return Int(bitPattern: (UInt(bitPattern: location) | (UInt(bitPattern: length) << 16)))
        #elseif arch(x86_64) || arch(arm64) || arch(s390x)
            return Int(bitPattern: (UInt(bitPattern: location) | (UInt(bitPattern: length) << 32)))
        #endif
    }
    
    public static func==(_ lhs: NSRange, _ rhs: NSRange) -> Bool {
        return lhs.location == rhs.location && lhs.length == rhs.length
    }
}

extension NSRange : CustomStringConvertible, CustomDebugStringConvertible {
    public var description: String { return "{\(location), \(length)}" }
    public var debugDescription: String {
        guard location != NSNotFound else {
            return "{NSNotFound, \(length)}"
        }
        return "{\(location), \(length)}"
    }
}

extension NSRange {
    public init?(_ string: String) {
        var savedLocation = 0
        if string.isEmpty {
            // fail early if the string is empty
            return nil
        }
        let scanner = Scanner(string: string)
        let digitSet = CharacterSet.decimalDigits
        let _ = scanner.scanUpToCharacters(from: digitSet, into: nil)
        if scanner.isAtEnd {
            // fail early if there are no decimal digits
            return nil
        }
        var location = 0
        savedLocation = scanner.scanLocation
        guard scanner.scanInt(&location) else {
            return nil
        }
        if scanner.isAtEnd {
            // return early if there are no more characters after the first int in the string
            return nil
        }
        if scanner.scanString(".", into: nil) {
            scanner.scanLocation = savedLocation
            var double = 0.0
            guard scanner.scanDouble(&double) else {
                return nil
            }
            guard let integral = Int(exactly: double) else {
                return nil
            }
            location = integral
        }
        
        let _ = scanner.scanUpToCharacters(from: digitSet, into: nil)
        if scanner.isAtEnd {
            // return early if there are no integer characters after the first int in the string
            return nil
        }
        var length = 0
        savedLocation = scanner.scanLocation
        guard scanner.scanInt(&length) else {
            return nil
        }
        
        if !scanner.isAtEnd {
            if scanner.scanString(".", into: nil) {
                scanner.scanLocation = savedLocation
                var double = 0.0
                guard scanner.scanDouble(&double) else {
                    return nil
                }
                guard let integral = Int(exactly: double) else {
                    return nil
                }
                length = integral
            }
        }
        
        
        self.location = location
        self.length = length
    }
}

extension NSRange {
    public var lowerBound: Int { return location }
    
    public var upperBound: Int { return location + length }
    
    public func contains(_ index: Int) -> Bool { return (!(index < location) && (index - location) < length) }
    
    public mutating func formUnion(_ other: NSRange) {
        self = union(other)
    }
    
    public func union(_ other: NSRange) -> NSRange {
        let max1 = location + length
        let max2 = other.location + other.length
        let maxend = (max1 < max2) ? max2 : max1
        let minloc = location < other.location ? location : other.location
        return NSRange(location: minloc, length: maxend - minloc)
    }
    
    public func intersection(_ other: NSRange) -> NSRange? {
        let max1 = location + length
        let max2 = other.location + other.length
        let minend = (max1 < max2) ? max1 : max2
        if other.location <= location && location < max2 {
            return NSRange(location: location, length: minend - location)
        } else if location <= other.location && other.location < max1 {
            return NSRange(location: other.location, length: minend - other.location);
        }
        return nil
    }
}


//===----------------------------------------------------------------------===//
// Ranges
//===----------------------------------------------------------------------===//

extension NSRange {
    public init<R: RangeExpression>(_ region: R)
        where R.Bound: FixedWidthInteger, R.Bound.Stride : SignedInteger {
            let r = region.relative(to: 0..<R.Bound.max)
            location = numericCast(r.lowerBound)
            length = numericCast(r.count)
    }
    
    public init<R: RangeExpression, S: StringProtocol>(_ region: R, in target: S)
        where R.Bound == S.Index, S.Index == String.Index {
            let r = region.relative(to: target)
            self = NSRange(
                location: r.lowerBound.encodedOffset - target.startIndex.encodedOffset,
                length: r.upperBound.encodedOffset - r.lowerBound.encodedOffset
            )
    }
    
    @available(swift, deprecated: 4, renamed: "Range.init(_:)")
    public func toRange() -> Range<Int>? {
        if location == NSNotFound { return nil }
        return location..<(location+length)
    }
}

extension Range where Bound: BinaryInteger {
    public init?(_ range: NSRange) {
        guard range.location != NSNotFound else { return nil }
        self.init(uncheckedBounds: (numericCast(range.lowerBound), numericCast(range.upperBound)))
    }
}

// This additional overload will mean Range.init(_:) defaults to Range<Int> when
// no additional type context is provided:
extension Range where Bound == Int {
    public init?(_ range: NSRange) {
        guard range.location != NSNotFound else { return nil }
        self.init(uncheckedBounds: (range.lowerBound, range.upperBound))
    }
}

extension Range where Bound == String.Index {
    public init?(_ range: NSRange, in string: String) {
        let u = string.utf16
        guard range.location != NSNotFound,
            let start = u.index(u.startIndex, offsetBy: range.location, limitedBy: u.endIndex),
            let end = u.index(u.startIndex, offsetBy: range.location + range.length, limitedBy: u.endIndex),
            let lowerBound = String.Index(start, within: string),
            let upperBound = String.Index(end, within: string)
            else { return nil }
        
        self = lowerBound..<upperBound
    }
}

extension NSRange : CustomReflectable {
    public var customMirror: Mirror {
        return Mirror(self, children: ["location": location, "length": length])
    }
}

extension NSRange : CustomPlaygroundQuickLookable {
    public var customPlaygroundQuickLook: PlaygroundQuickLook {
        return .range(Int64(location), Int64(length))
    }
}

extension NSRange : Codable {
    public init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        let location = try container.decode(Int.self)
        let length = try container.decode(Int.self)
        self.init(location: location, length: length)
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        try container.encode(self.location)
        try container.encode(self.length)
    }
}

#if DEPLOYMENT_RUNTIME_SWIFT

    
extension NSRange {
    internal init(_ range: CFRange) {
        location = range.location == kCFNotFound ? NSNotFound : range.location
        length = range.length
    }
}
    
extension CFRange {
    internal init(_ range: NSRange) {
        location = range.location == NSNotFound ? kCFNotFound : range.location
        length = range.length
    }
}
    
extension NSRange {
    public init(_ x: Range<Int>) {
        location = x.lowerBound
        length = x.count
    }
    
    internal func toCountableRange() -> CountableRange<Int>? {
        if location == NSNotFound { return nil }
        return location..<(location+length)
    }
}
    
extension NSRange: NSSpecialValueCoding {
    init(bytes: UnsafeRawPointer) {
        self.location = bytes.load(as: Int.self)
        self.length = bytes.load(fromByteOffset: MemoryLayout<Int>.stride, as: Int.self)
    }
    
    init?(coder aDecoder: NSCoder) {
        guard aDecoder.allowsKeyedCoding else {
            preconditionFailure("Unkeyed coding is unsupported.")
        }
        if let location = aDecoder.decodeObject(of: NSNumber.self, forKey: "NS.rangeval.location") {
            self.location = location.intValue
        } else {
            self.location = 0
        }
        if let length = aDecoder.decodeObject(of: NSNumber.self, forKey: "NS.rangeval.length") {
            self.length = length.intValue
        } else {
            self.length = 0
        }
    }
    
    func encodeWithCoder(_ aCoder: NSCoder) {
        guard aCoder.allowsKeyedCoding else {
            preconditionFailure("Unkeyed coding is unsupported.")
        }
        aCoder.encode(NSNumber(value: self.location), forKey: "NS.rangeval.location")
        aCoder.encode(NSNumber(value: self.length), forKey: "NS.rangeval.length")
    }
    
    static func objCType() -> String {
#if arch(i386) || arch(arm)
        return "{_NSRange=II}"
#elseif arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
        return "{_NSRange=QQ}"
#else
        NSUnimplemented()
#endif
    }
    
    func getValue(_ value: UnsafeMutableRawPointer) {
        value.initializeMemory(as: NSRange.self, repeating: self, count: 1)
    }
    
    func isEqual(_ aValue: Any) -> Bool {
        if let other = aValue as? NSRange {
            return other.location == self.location && other.length == self.length
        } else {
            return false
        }
    }
    
    var hash: Int { return hashValue }
}
    
extension NSValue {
    public convenience init(range: NSRange) {
        self.init()
        self._concreteValue = NSSpecialValue(range)
    }
    
    public var rangeValue: NSRange {
        let specialValue = self._concreteValue as! NSSpecialValue
        return specialValue._value as! NSRange
    }
}
#endif
