// 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
//


import CoreFoundation

internal class _NSCFString : NSMutableString {
    required init(characters: UnsafePointer<unichar>, length: Int) {
        fatalError()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    required init(extendedGraphemeClusterLiteral value: StaticString) {
        fatalError()
    }

    required init(stringLiteral value: StaticString) {
        fatalError()
    }

    required init(capacity: Int) {
        fatalError()
    }

    required init(string aString: String) {
        fatalError()
    }
    
    deinit {
        _CFDeinit(self)
        _CFZeroUnsafeIvars(&_storage)
    }
    
    override var length: Int {
        return CFStringGetLength(unsafeBitCast(self, to: CFString.self))
    }
    
    override func character(at index: Int) -> unichar {
        return CFStringGetCharacterAtIndex(unsafeBitCast(self, to: CFString.self), index)
    }
    
    override func replaceCharacters(in range: NSRange, with aString: String) {
        CFStringReplace(unsafeBitCast(self, to: CFMutableString.self), CFRangeMake(range.location, range.length), aString._cfObject)
    }
    
    override var classForCoder: AnyClass {
        return NSMutableString.self
    }
}

internal final class _NSCFConstantString : _NSCFString {
    internal var _ptr : UnsafePointer<UInt8> {
        // FIXME: Split expression as a work-around for slow type
        //        checking (tracked by SR-5322).
        let offTemp1 = MemoryLayout<OpaquePointer>.size + MemoryLayout<Int32>.size
        let offTemp2 = MemoryLayout<Int32>.size + MemoryLayout<_CFInfo>.size
        let offset = offTemp1 + offTemp2
        let ptr = Unmanaged.passUnretained(self).toOpaque()
        return ptr.load(fromByteOffset: offset, as: UnsafePointer<UInt8>.self)
    }

    private var _lenOffset : Int {
        // FIXME: Split expression as a work-around for slow type
        //        checking (tracked by SR-5322).
        let offTemp1 = MemoryLayout<OpaquePointer>.size + MemoryLayout<Int32>.size
        let offTemp2 = MemoryLayout<Int32>.size + MemoryLayout<_CFInfo>.size
        return offTemp1 + offTemp2 + MemoryLayout<UnsafePointer<UInt8>>.size
    }

    private var _lenPtr :  UnsafeMutableRawPointer {
        return Unmanaged.passUnretained(self).toOpaque()
    }

#if arch(s390x)
    internal var _length : UInt64 {
        return _lenPtr.load(fromByteOffset: _lenOffset, as: UInt64.self)
    }
#else
    internal var _length : UInt32 {
        return _lenPtr.load(fromByteOffset: _lenOffset, as: UInt32.self)
    }
#endif
    
    required init(characters: UnsafePointer<unichar>, length: Int) {
        fatalError()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }
    
    required init(extendedGraphemeClusterLiteral value: StaticString) {
        fatalError()
    }
    
    required init(stringLiteral value: StaticString) {
        fatalError()
    }
    
    required init(capacity: Int) {
        fatalError()
    }

    required init(string aString: String) {
        fatalError("Constant strings cannot be constructed in code")
    }
    
    deinit {
        fatalError("Constant strings cannot be deallocated")
    }

    override var length: Int {
        return Int(_length)
    }
    
    override func character(at index: Int) -> unichar {
        return unichar(_ptr[index])
    }
    
    override func replaceCharacters(in range: NSRange, with aString: String) {
        fatalError()
    }
    
    override var classForCoder: AnyClass {
        return NSString.self
    }
}

internal func _CFSwiftStringGetLength(_ string: AnyObject) -> CFIndex {
    return (string as! NSString).length
}

internal func _CFSwiftStringGetCharacterAtIndex(_ str: AnyObject, index: CFIndex) -> UniChar {
    return (str as! NSString).character(at: index)
}

internal func _CFSwiftStringGetCharacters(_ str: AnyObject, range: CFRange, buffer: UnsafeMutablePointer<UniChar>) {
    (str as! NSString).getCharacters(buffer, range: NSRange(location: range.location, length: range.length))
}

internal func _CFSwiftStringGetBytes(_ str: AnyObject, encoding: CFStringEncoding, range: CFRange, buffer: UnsafeMutablePointer<UInt8>?, maxBufLen: CFIndex, usedBufLen: UnsafeMutablePointer<CFIndex>?) -> CFIndex {
    let convertedLength: CFIndex
    switch encoding {
        // TODO: Don't treat many encodings like they are UTF8
    case CFStringEncoding(kCFStringEncodingUTF8), CFStringEncoding(kCFStringEncodingISOLatin1), CFStringEncoding(kCFStringEncodingMacRoman), CFStringEncoding(kCFStringEncodingASCII), CFStringEncoding(kCFStringEncodingNonLossyASCII):
        let encodingView = (str as! NSString).substring(with: NSRange(range)).utf8
        if let buffer = buffer {
            for (idx, character) in encodingView.enumerated() {
                buffer.advanced(by: idx).initialize(to: character)
            }
        }
        usedBufLen?.pointee = encodingView.count
        convertedLength = encodingView.count
        
    case CFStringEncoding(kCFStringEncodingUTF16):
        let encodingView = (str as! NSString)._swiftObject.utf16
        let start = encodingView.startIndex
        if let buffer = buffer {
            for idx in 0..<range.length {
                // Since character is 2 bytes but the buffer is in term of 1 byte values, we have to split it up
                let character = encodingView[encodingView.index(start, offsetBy: idx + range.location)]
#if _endian(big)
                let byte0 = UInt8((character >> 8) & 0x00ff)
                let byte1 = UInt8(character & 0x00ff)
#else
                let byte0 = UInt8(character & 0x00ff)
                let byte1 = UInt8((character >> 8) & 0x00ff)
#endif
                buffer.advanced(by: idx * 2).initialize(to: byte0)
                buffer.advanced(by: (idx * 2) + 1).initialize(to: byte1)
            }
        }
        // Every character was 2 bytes
        usedBufLen?.pointee = range.length * 2
        convertedLength = range.length

    default:
        fatalError("Attempted to get bytes of a Swift string using an unsupported encoding")
    }
    
    return convertedLength
}

internal func _CFSwiftStringCreateWithSubstring(_ str: AnyObject, range: CFRange) -> Unmanaged<AnyObject> {
    return Unmanaged<AnyObject>.passRetained((str as! NSString).substring(with: NSRange(location: range.location, length: range.length))._nsObject)
}


internal func _CFSwiftStringCreateCopy(_ str: AnyObject) -> Unmanaged<AnyObject> {
    return Unmanaged<AnyObject>.passRetained((str as! NSString).copy() as! NSObject)
}

internal func _CFSwiftStringCreateMutableCopy(_ str: AnyObject) -> Unmanaged<AnyObject> {
    return Unmanaged<AnyObject>.passRetained((str as! NSString).mutableCopy() as! NSObject)
}

internal func _CFSwiftStringFastCStringContents(_ str: AnyObject, _ nullTerminated: Bool) -> UnsafePointer<Int8>? {
    return (str as! NSString)._fastCStringContents(nullTerminated)
}

internal func _CFSwiftStringFastContents(_ str: AnyObject) -> UnsafePointer<UniChar>? {
    return (str as! NSString)._fastContents
}

internal func _CFSwiftStringGetCString(_ str: AnyObject, buffer: UnsafeMutablePointer<Int8>, maxLength: Int, encoding: CFStringEncoding) -> Bool {
    return (str as! NSString).getCString(buffer, maxLength: maxLength, encoding: CFStringConvertEncodingToNSStringEncoding(encoding))
}

internal func _CFSwiftStringIsUnicode(_ str: AnyObject) -> Bool {
    return (str as! NSString)._encodingCantBeStoredInEightBitCFString
}

internal func _CFSwiftStringInsert(_ str: AnyObject, index: CFIndex, inserted: AnyObject) {
    (str as! NSMutableString).insert((inserted as! NSString)._swiftObject, at: index)
}

internal func _CFSwiftStringDelete(_ str: AnyObject, range: CFRange) {
    (str as! NSMutableString).deleteCharacters(in: NSRange(location: range.location, length: range.length))
}

internal func _CFSwiftStringReplace(_ str: AnyObject, range: CFRange, replacement: AnyObject) {
    (str as! NSMutableString).replaceCharacters(in: NSRange(location: range.location, length: range.length), with: (replacement as! NSString)._swiftObject)
}

internal func _CFSwiftStringReplaceAll(_ str: AnyObject, replacement: AnyObject) {
    (str as! NSMutableString).setString((replacement as! NSString)._swiftObject)
}

internal func _CFSwiftStringAppend(_ str: AnyObject, appended: AnyObject) {
    (str as! NSMutableString).append((appended as! NSString)._swiftObject)
}

internal func _CFSwiftStringAppendCharacters(_ str: AnyObject, chars: UnsafePointer<UniChar>, length: CFIndex) {
    (str as! NSMutableString).appendCharacters(chars, length: length)
}

internal func _CFSwiftStringAppendCString(_ str: AnyObject, chars: UnsafePointer<Int8>, length: CFIndex) {
    (str as! NSMutableString)._cfAppendCString(chars, length: length)
}

