//===--- CollectionCasts.swift.gyb ----------------------------*- swift -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/CollectionCasts.swift
// RUN: %line-directive %t/CollectionCasts.swift -- %target-build-swift %t/CollectionCasts.swift -o %t/a.out
// RUN: %target-codesign %t/a.out && %line-directive %t/CollectionCasts.swift -- %target-run %t/a.out 2>&1
// REQUIRES: executable_test

import StdlibUnittest

class Base : Hashable {
  init(_ value: Int) {
    self.value = value
  }
  var value: Int
  var hashValue : Int {
    return value.hashValue
  }
}

func == (lhs: Base, rhs: Base) -> Bool {
  return lhs.value == rhs.value
}

class Derived : Base {}

protocol AnyFoo {
  init(_ value: Int)
}
extension Int : AnyFoo { }

var tests = TestSuite("CollectionCasts")

// A wrapper for an as? cast that suppresses warnings when the cast always
// succeeds.
func cast<T, U>(_ x: T, to result: U.Type) -> U? {
  return x as? U
}

%{
classKeys = ('Derived', 'Base')
classValues = classKeys + ('AnyObject', 'Any')
nonClassKeys = ('Int',)
nonClassValues = ('Int', 'AnyFoo', 'Any')
}%

% for keys, values in [ (classKeys, classValues), (nonClassKeys, nonClassValues) ]:

%   for ki0, Key0 in enumerate(keys):
%     DynamicKey = keys[0] if Key0.startswith('Any') else Key0
%     for Key1 in keys[ki0:]:
%       for Collection in 'Array', 'Set':

tests.test("${Collection}/Up/${Key0}=>${Key1}") {

  let source : ${Collection} = [
    ${DynamicKey}(42) as ${Key0},
    ${DynamicKey}(17) as ${Key0}]

  let upcasted = source as ${Collection}<${Key1}>

  expectEqual(source.count, upcasted.count)
  for x in source {
    expectTrue(upcasted.contains(x))
  }
}

%         if Key1 != Key0:
%           for method in 'Direct', 'Indirect':
tests.test("${Collection}/Down/${method}/${Key1}=>${Key0}") {

  let source : ${Collection} = [
    ${DynamicKey}(42) as ${Key1},
    ${DynamicKey}(17) as ${Key1}]

%             if method == 'Direct':

  guard let downcasted = expectNotNil(source as? ${Collection}<${Key0}>)
  else { return }

%             else:

  guard let downcasted = expectNotNil(cast(source, to: ${Collection}<${Key0}>.self))
  else { return }

%             end

  expectEqual(source.count, downcasted.count)
  for x in downcasted {
    expectTrue(source.contains(x))
  }
}
%           end
%         end
%       end


%       for vi0, Value0 in enumerate(values):
%         DynamicValue = values[0] if Value0.startswith('Any') else Value0
%         for Value1 in values[vi0:]:

%           for method in 'Direct', 'Indirect':

tests.test(
  "Dictionary/Up/${method}/[${Key0}:${Value0}]=>[${Key1}:${Value1}]") {

  // Check that the cast type-checks
  let source = [
    ${DynamicKey}(42) as ${Key0} : ${DynamicValue}(42) as ${Value0},
    ${DynamicKey}(17) as ${Key0} : ${DynamicValue}(17) as ${Value0}]


%   if method == 'Direct':
  let upcasted = source as [${Key1}:${Value1}]
%   else:
  let upcasted_ = source as Any as? [${Key1}:${Value1}]

  guard let upcasted = expectNotNil(upcasted_) else { return }
%   end

  expectEqual(source.count, upcasted.count)

  for (k0, v0) in source {
    guard let v1 = expectNotNil(upcasted[k0]) else { continue }

    guard let dv0 = expectNotNil(
      cast(v0, to: ${DynamicValue}.self)) else { continue }

    guard let dv1 = expectNotNil(
      cast(v1, to: ${DynamicValue}.self)) else { continue }

    expectEqual(dv0, dv1)
  }
}

% end

% if Key1 != Key0 or Value1 != Value0:

tests.test(
  "Dictionary/Down/[${Key1}:${Value1}]=>[${Key0}:${Value0}]") {

  // Check that the cast type-checks
  let source = [
    ${DynamicKey}(42) as ${Key1} : ${DynamicValue}(42) as ${Value1},
    ${DynamicKey}(17) as ${Key1} : ${DynamicValue}(17) as ${Value1}]

  guard let downcasted = expectNotNil(source as? [${Key0}:${Value0}])
  else { return }

  expectEqual(source.count, downcasted.count)

  for (k0, v0) in downcasted {
    guard let v1 = expectNotNil(source[k0]) else { continue }

    guard let dv0 = expectNotNil(
      cast(v0, to: ${DynamicValue}.self)) else { continue }

    guard let dv1 = expectNotNil(
      cast(v1, to: ${DynamicValue}.self)) else { continue }

    expectEqual(dv0, dv1)
  }
}

% end

%         end
%       end
%     end
%   end
% end


runAllTests()

