// -*- swift -*-
// RUN: %target-run-simple-swiftgyb
// REQUIRES: executable_test

%{
from gyb_stdlib_support import (
    TRAVERSALS,
    sliceTypeName,
    defaultIndicesForTraversal
)
}%

import StdlibUnittest
import StdlibCollectionUnittest


/// Reference-type collection for testing the `base` property.
class ReferenceCollection : RandomAccessCollection {
  typealias Index = Int

  var startIndex: Int {
    return 0
  }

  var endIndex: Int {
    return 1
  }

  subscript(index: Int) -> String {
    return ""
  }

  func index(after i: Int) -> Int {
    return 1
  }

  func index(before i: Int) -> Int {
    return 0
  }
}

var SliceTests = TestSuite("Collection")

//===----------------------------------------------------------------------===//
// Slice<Base>
//===----------------------------------------------------------------------===//

% for Traversal in TRAVERSALS:
%   for Mutable in [ False, True ]:
%     for RangeReplaceable in [ False, True ]:
%       Slice = sliceTypeName(traversal=Traversal, mutable=Mutable, rangeReplaceable=RangeReplaceable)
%       Collection = 'Minimal' + Slice.replace('Slice', 'Collection')

SliceTests.test("${Slice}/AssociatedTypes") {
 do {
    typealias Collection = ${Collection}<OpaqueValue<Int>>
    typealias CollectionSlice = ${Slice}<Collection>
    expectSliceType(CollectionSlice.self)
    expectCollectionAssociatedTypes(
      collectionType: CollectionSlice.self,
      iteratorType: IndexingIterator<CollectionSlice>.self,
      subSequenceType: CollectionSlice.self,
      indexType: MinimalIndex.self,
      indexDistanceType: Int.self,
      indicesType: ${defaultIndicesForTraversal(Traversal)}<CollectionSlice>.self)
  }

  func checkStaticTypealiases1<Base : Collection>(_: Base) {
    expectEqualType(Base.Index.self, Slice<Base>.Index.self)
  }

  func checkStaticTypealiases2<
    Base : MutableCollection
  >(_: Base) {
    expectEqualType(Base.Index.self, MutableSlice<Base>.Index.self)
  }
}

SliceTests.test("${Slice}/init(base:bounds:)") {
  for test in subscriptRangeTests {
    let base = ${Collection}(elements: test.collection)
    var slice = ${Slice}(base: base, bounds: test.bounds(in: base))
    expectType(${Slice}<${Collection}<OpaqueValue<Int>>>.self, &slice)

    checkCollection(
      slice,
      expected: test.expected,
      stackTrace: SourceLocStack().with(test.loc))
      { $0.value == $1.value }
  }
}

% if RangeReplaceable == False and Mutable == False:
SliceTests.test("${Slice}/baseProperty") {
  let referenceCollection = ReferenceCollection()
  let testSlice = ${Slice}(base: referenceCollection, bounds: 0..<1)
  expectTrue(testSlice.base === referenceCollection)
}
% end

SliceTests.test("${Slice}.{startIndex,endIndex}") {
  for test in subscriptRangeTests {
    let c = ${Collection}(elements: test.collection)
    let bounds = test.bounds(in: c)
    var slice = ${Slice}(base: c, bounds: bounds)
    expectType(${Slice}<${Collection}<OpaqueValue<Int>>>.self, &slice)

    expectEqual(bounds.lowerBound, slice.startIndex)
    expectEqual(bounds.upperBound, slice.endIndex)
  }
}

%     end
%   end
% end

//===----------------------------------------------------------------------===//
// MutableSlice<Base>
//===----------------------------------------------------------------------===//

/*
FIXME: uncomment this test when the following bug is fixed:

<rdar://problem/21935030> Recast Slice and MutableSlice in terms of Collection
and MutableCollection

extension MutableSlice {
  func _checkBaseSubSequenceElementIsElement() {
      Element.self,
      Iterator.Element.self)
    expectEqualType(
      Element.self,
      Iterator.Element.self,
      Base.Iterator.Element.self)
    expectEqualType(
      Element.self,
      Iterator.Element.self,
      Base.SubSequence.Iterator.Element.self)
  }
}
*/

runAllTests()
