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

extension String {
  // FIXME(strings): at least temporarily remove it to see where it was applied
  /// Creates a new string from the given substring.
  ///
  /// - Parameter substring: A substring to convert to a standalone `String`
  ///   instance.
  ///
  /// - Complexity: O(*n*), where *n* is the length of `substring`.
  public init(_ substring: Substring) {
    self = String(substring._slice)
  }
}

/// A slice of a string.
///
/// When you create a slice of a string, a `Substring` instance is the result.
/// Operating on substrings is fast and efficient because a substring shares
/// its storage with the original string. The `Substring` type presents the
/// same interface as `String`, so you can avoid or defer any copying of the
/// string's contents.
///
/// The following example creates a `greeting` string, and then finds the
/// substring of the first sentence:
///
///     let greeting = "Hi there! It's nice to meet you! 👋"
///     let endOfSentence = greeting.index(of: "!")!
///     let firstSentence = greeting[...endOfSentence]
///     // firstSentence == "Hi there!"
///
/// You can perform many string operations on a substring. Here, we find the
/// length of the first sentence and create an uppercase version.
///
///     print("'\(firstSentence)' is \(firstSentence.count) characters long.")
///     // Prints "'Hi there!' is 9 characters long."
///
///     let shoutingSentence = firstSentence.uppercased()
///     // shoutingSentence == "HI THERE!"
///
/// Converting a Substring to a String
/// ==================================
///
/// This example defines a `rawData` string with some unstructured data, and
/// then uses the string's `prefix(while:)` method to create a substring of
/// the numeric prefix:
///
///     let rawInput = "126 a.b 22219 zzzzzz"
///     let numericPrefix = rawInput.prefix(while: { "0"..."9" ~= $0 })
///     // numericPrefix is the substring "126"
///
/// When you need to store a substring or pass it to a function that requires a
/// `String` instance, convert it using the `String.init(_:)` initializer.
///
///     _ = Int(numericPrefix, radix: 10)
///     // error: cannot convert value...
///     let prefix = Int(String(numericPrefix), radix: 10)
///     // prefix == 126
///
/// Calling this initializer copies the contents of the substring to a new
/// string.
///
/// - Important: Don't store substrings longer than you need them to perform a
///   specific operation. A substring holds a reference to the entire storage
///   of the string it comes from, not just to the portion it presents, even
///   when there is no other reference to the original string. Storing
///   substrings may, therefore, prolong the lifetime of string data that is
///   no longer otherwise accessible, which can appear to be memory leakage.
public struct Substring : StringProtocol {
  public typealias Index = String.Index
  public typealias IndexDistance = String.IndexDistance
  public typealias SubSequence = Substring

  internal var _slice: RangeReplaceableBidirectionalSlice<String>

  /// Creates an empty substring.
  public init() {
    _slice = RangeReplaceableBidirectionalSlice()
  }

  internal init(_slice: RangeReplaceableBidirectionalSlice<String>) {
    self._slice = _slice
  }
  
  /// Creates a substring with the specified bounds within the given string.
  ///
  /// - Parameters:
  ///   - base: The string to create a substring of.
  ///   - bounds: The range of `base` to use for the substring. The lower and
  ///     upper bounds of `bounds` must be valid indices of `base`.
  public init(_base base: String, _ bounds: Range<Index>) {
    _slice = RangeReplaceableBidirectionalSlice(base: base, bounds: bounds)
  }

  internal init<R: RangeExpression>(
    _base base: String, _ bounds: R
  ) where R.Bound == Index {
    self.init(_base: base, bounds.relative(to: base))
  }

  public var startIndex: Index { return _slice.startIndex }
  public var endIndex: Index { return _slice.endIndex }

  public func index(after i: Index) -> Index {
    _precondition(i < endIndex, "Cannot increment beyond endIndex")
    _precondition(i >= startIndex, "Cannot increment an invalid index")
    // FIXME(strings): slice types currently lack necessary bound checks
    return _slice.index(after: i)
  }

  public func index(before i: Index) -> Index {
    _precondition(i <= endIndex, "Cannot decrement an invalid index")
    _precondition(i > startIndex, "Cannot decrement beyond startIndex")
    // FIXME(strings): slice types currently lack necessary bound checks
    return _slice.index(before: i)
  }

  public func index(_ i: Index, offsetBy n: IndexDistance) -> Index {
    let result = _slice.index(i, offsetBy: n)
    // FIXME(strings): slice types currently lack necessary bound checks
    _precondition(
      (_slice._startIndex ... _slice.endIndex).contains(result),
      "Operation results in an invalid index")
    return result
  }

  public func index(
    _ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index
  ) -> Index? {
    let result = _slice.index(i, offsetBy: n, limitedBy: limit)
    // FIXME(strings): slice types currently lack necessary bound checks
    _precondition(result.map {
        (_slice._startIndex ... _slice.endIndex).contains($0)
      } ?? true,
      "Operation results in an invalid index")
    return result
  }

  public func distance(from start: Index, to end: Index) -> IndexDistance {
    return _slice.distance(from: start, to: end)
  }

  public subscript(i: Index) -> Character {
    return _slice[i]
  }

  public mutating func replaceSubrange<C>(
    _ bounds: Range<Index>,
    with newElements: C
  ) where C : Collection, C.Iterator.Element == Iterator.Element {
    // FIXME(strings): slice types currently lack necessary bound checks
    _slice.replaceSubrange(bounds, with: newElements)
  }

% for Range in ['Range', 'ClosedRange']:

  public mutating func replaceSubrange(
    _ bounds: ${Range}<Index>, with newElements: Substring
  ) {
    replaceSubrange(bounds, with: newElements._slice)
  }

% end

  /// Creates a string from the given Unicode code units in the specified
  /// encoding.
  ///
  /// - Parameters:
  ///   - codeUnits: A collection of code units encoded in the ecoding
  ///     specified in `sourceEncoding`.
  ///   - sourceEncoding: The encoding in which `codeUnits` should be
  ///     interpreted.
  public init<C: Collection, Encoding: _UnicodeEncoding>(
    decoding codeUnits: C, as sourceEncoding: Encoding.Type
  ) where C.Iterator.Element == Encoding.CodeUnit {
    self.init(String(decoding: codeUnits, as: sourceEncoding))
  }

  /// Creates a string from the null-terminated, UTF-8 encoded sequence of
  /// bytes at the given pointer.
  ///
  /// - Parameter nullTerminatedUTF8: A pointer to a sequence of contiguous,
  ///   UTF-8 encoded bytes ending just before the first zero byte.
  public init(cString nullTerminatedUTF8: UnsafePointer<CChar>) {
    self.init(String(cString: nullTerminatedUTF8))
  }

  /// Creates a string from the null-terminated sequence of bytes at the given
  /// pointer.
  ///
  /// - Parameters:
  ///   - nullTerminatedCodeUnits: A pointer to a sequence of contiguous code
  ///     units in the encoding specified in `sourceEncoding`, ending just
  ///     before the first zero code unit.
  ///   - sourceEncoding: The encoding in which the code units should be
  ///     interpreted.
  public init<Encoding: _UnicodeEncoding>(
    decodingCString nullTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>,
    as sourceEncoding: Encoding.Type
  ) {
    self.init(
      String(decodingCString: nullTerminatedCodeUnits, as: sourceEncoding))
  }

  /// Calls the given closure with a pointer to the contents of the string,
  /// represented as a null-terminated sequence of UTF-8 code units.
  ///
  /// The pointer passed as an argument to `body` is valid only during the
  /// execution of `withCString(_:)`. Do not store or return the pointer for
  /// later use.
  ///
  /// - Parameter body: A closure with a pointer parameter that points to a
  ///   null-terminated sequence of UTF-8 code units. If `body` has a return
  ///   value, that value is also used as the return value for the
  ///   `withCString(_:)` method. The pointer argument is valid only for the
  ///   duration of the method's execution.
  /// - Returns: The return value, if any, of the `body` closure parameter.
  public func withCString<Result>(
    _ body: (UnsafePointer<CChar>) throws -> Result) rethrows -> Result {
    return try _slice._base._core._withCSubstringAndLength(
      in: startIndex._base._position..<endIndex._base._position,
      encoding: UTF8.self) {
      p, length in try p.withMemoryRebound(to: CChar.self, capacity: length) {
        try body($0)
      }
    }
  }

  /// Calls the given closure with a pointer to the contents of the string,
  /// represented as a null-terminated sequence of code units.
  ///
  /// The pointer passed as an argument to `body` is valid only during the
  /// execution of `withCString(encodedAs:_:)`. Do not store or return the
  /// pointer for later use.
  ///
  /// - Parameters:
  ///   - body: A closure with a pointer parameter that points to a
  ///     null-terminated sequence of code units. If `body` has a return
  ///     value, that value is also used as the return value for the
  ///     `withCString(encodedAs:_:)` method. The pointer argument is valid
  ///     only for the duration of the method's execution.
  ///   - targetEncoding: The encoding in which the code units should be
  ///     interpreted.
  /// - Returns: The return value, if any, of the `body` closure parameter.
  public func withCString<Result, TargetEncoding: _UnicodeEncoding>(
    encodedAs targetEncoding: TargetEncoding.Type,
    _ body: (UnsafePointer<TargetEncoding.CodeUnit>) throws -> Result
  ) rethrows -> Result {
    return try _slice._base._core._withCSubstring(
      in: startIndex._base._position..<endIndex._base._position,
      encoding: targetEncoding, body)
  }
}

extension Substring : _SwiftStringView {
  var _persistentContent : String {
    let wholeCore = _slice._base._core
    let native = wholeCore.nativeBuffer
    if _fastPath(native != nil), let n = native {
      if _fastPath(
        n.start == wholeCore._baseAddress && n.usedCount == wholeCore.count) {
        return String(wholeCore)
      }
    }
    var r = String()
    r._core.append(_ephemeralContent._core)
    _sanityCheck(r._core._owner !== _ephemeralContent._core._owner)
    return r
  }

  public // @testablw
  var _ephemeralContent : String {
    let wholeCore = _slice._base._core
    let subCore : _StringCore = wholeCore[
      startIndex._base._position..<endIndex._base._position]
    // check that we haven't allocated a new buffer for the result
    _sanityCheck(subCore._owner === wholeCore._owner)
    return String(subCore)
  }
}

extension Substring : CustomReflectable {
  public var customMirror: Mirror {
    return String(self).customMirror
  }
}

extension Substring : CustomPlaygroundQuickLookable {
  public var customPlaygroundQuickLook: PlaygroundQuickLook {
    return String(self).customPlaygroundQuickLook
  }
}

extension Substring : CustomStringConvertible {
  public var description: String {
    return String(self)
  }
}

extension Substring : CustomDebugStringConvertible {
  public var debugDescription: String {
    return String(self).debugDescription
  }
}

extension Substring : LosslessStringConvertible {
  public init(_ content: String) {
    self.init(_base: content, content.startIndex ..< content.endIndex)
  }
}

extension StringProtocol {
  public static func ==<R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return lhs._ephemeralString == rhs._ephemeralString
  }

  public static func !=<R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return lhs._ephemeralString != rhs._ephemeralString
  }
}

extension StringProtocol {
  public static func < <R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return lhs._ephemeralString < rhs._ephemeralString
  }

  public static func > <R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return rhs < lhs
  }

  public static func <= <R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return !(rhs < lhs)
  }

  public static func >= <R: StringProtocol>(lhs: Self, rhs: R) -> Bool {
    return !(lhs < rhs)
  }
}

extension StringProtocol {
  public var hashValue : Int {
    return self._ephemeralString.hashValue
  }
}

extension Substring {
% for (property, ViewPrefix) in [
%   ('utf8', 'UTF8'),
%   ('utf16', 'UTF16'),
%   ('unicodeScalars', 'UnicodeScalar'),
%   ('characters', 'Character')]:
  public typealias ${ViewPrefix}Index = String.${ViewPrefix}View.Index

  public var ${property}: String.${ViewPrefix}View {
    get {
      return String(self).${property}
    }
    set {
      let base = String(describing: newValue)
      self = Substring(_base: base, base.startIndex ..< base.endIndex)
    }
  }
% end
}

#if _runtime(_ObjC)

extension Substring {
  public func hasPrefix(_ prefix: String) -> Bool {
    return String(self).hasPrefix(prefix)
  }

  public func hasSuffix(_ suffix: String) -> Bool {
    return String(self).hasSuffix(suffix)
  }
}

#endif

extension Substring : RangeReplaceableCollection {
  public init<S : Sequence>(_ elements: S)
  where S.Element == Character {
    let e0 = elements as? _SwiftStringView
    if _fastPath(e0 != nil), let e = e0 {
      self = e._ephemeralContent[...]
    }
    else {
      self = String(elements)[...]
    }
  }
  
  public mutating func append<S : Sequence>(contentsOf elements: S)
  where S.Element == Character {
    var c = self._ephemeralContent._core
    self = Substring()
    
    let e0 = elements as? _SwiftStringView
    if _fastPath(e0 != nil), let e1 = e0 {
      c.append(contentsOf: e1._ephemeralContent.utf16)
      self = String(c)[...]
    }
    else {
      var s = String(c)
      s.append(contentsOf: elements)
      self = s[...]
    }
  }
}

extension Substring {
  public func lowercased() -> String {
    return String(self).lowercased()
  }

  public func uppercased() -> String {
    return String(self).uppercased()
  }
}

extension Substring : TextOutputStream {
  public mutating func write(_ other: String) {
    append(contentsOf: other)
  }
}

extension Substring : TextOutputStreamable {
  public func write<Target : TextOutputStream>(to target: inout Target) {
    target.write(String(self))
  }
}

extension Substring : ExpressibleByUnicodeScalarLiteral {
  public init(unicodeScalarLiteral value: String) {
     self.init(_base: value, value.startIndex ..< value.endIndex)
  }
}
extension Substring : ExpressibleByExtendedGraphemeClusterLiteral {
  public init(extendedGraphemeClusterLiteral value: String) {
     self.init(_base: value, value.startIndex ..< value.endIndex)
  }
}

extension Substring : ExpressibleByStringLiteral {
  public init(stringLiteral value: String) {
     self.init(_base: value, value.startIndex ..< value.endIndex)
  }
}

//===--- String/Substring Slicing Support ---------------------------------===//
/// In Swift 3.2, in the absence of type context,
///
///     someString[someString.startIndex..<someString.endIndex]
///
/// was deduced to be of type `String`.  Therefore have a more-specific
/// Swift-3-only `subscript` overload on `String` (and `Substring`) that
/// continues to produce `String`.
extension String {
  @available(swift, introduced: 4)
  public subscript(r: Range<Index>) -> Substring {
    return Substring(
      _slice: RangeReplaceableBidirectionalSlice(base: self, bounds: r))
  }

  @available(swift, obsoleted: 4)
  public subscript(bounds: Range<Index>) -> String {
    return String(characters[bounds])
  }

  @available(swift, obsoleted: 4)
  public subscript(bounds: ClosedRange<Index>) -> String {
    return String(characters[bounds])
  }
}

extension Substring {
  @available(swift, introduced: 4)
  public subscript(r: Range<Index>) -> Substring {
    return Substring(_slice: _slice[r])
  }

  @available(swift, obsoleted: 4)
  public subscript(bounds: Range<Index>) -> String {
    return String(characters[bounds])
  }

  @available(swift, obsoleted: 4)
  public subscript(bounds: ClosedRange<Index>) -> String {
    return String(characters[bounds])
  }
}
//===----------------------------------------------------------------------===//
