// -*- 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()
