// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:collection';

import 'package:expect/expect.dart';

class CustomMap with MapMixin<int, String> {
  Iterable<int> get keys => [];
  String operator [](Object key) => "";
  operator []=(int key, String value) {}
  String remove(Object key) => throw UnsupportedError("unsupported");
  void clear() => throw UnsupportedError("unsupported");
}

class CustomSet extends SetBase<int> {
  bool add(int value) => throw UnsupportedError("unsupported");
  bool contains(Object value) => throw UnsupportedError("unsupported");
  Iterator<int> get iterator => <int>[].iterator;
  int get length => 0;
  int lookup(Object value) => throw UnsupportedError("unsupported");
  bool remove(Object value) => throw UnsupportedError("unsupported");
  Set<int> toSet() => this;
}

class Equality {
  final int id;
  final String name;
  const Equality(this.id, this.name);
  int get hashCode => id;
  bool operator ==(Object other) => other is Equality && id == other.id;
  String toString() => "$id:$name";
}

T expectDynamic<T>(dynamic value) {
  Expect.identical(dynamic, T);
  return value;
}

T expectInt<T>(dynamic value) {
  Expect.identical(int, T);
  return value;
}

T expectString<T>(dynamic value) {
  Expect.identical(String, T);
  return value;
}

Set<T> expectIntSet<T>() {
  Expect.identical(int, T);
  return Set();
}

Set<T> expectDynamicSet<T>() {
  Expect.identical(dynamic, T);
  return Set();
}

/// Hacky way of testing the inferred generic type arguments of [object].
///
/// [Expect.type()] only performs a subtype test, which means that it will
/// return `true` when asked if a `List<int>` is a `List<num>` or
/// `List<dynamic>`. For inference, we want to test the type more precisely.
///
/// There isn't a good way to do that in tests yet so, for now, we just see if
/// the runtime type contains the given type argument string.
// TODO(rnystrom): Do something less horribly brittle.
void _expectTypeArguments(String typeArguments, Object object) {
  var typeName = object.runtimeType.toString();

  // If an implementation prints dynamic instantiations like a raw type,
  // handle that.
  if (!typeName.contains("<") &&
      (typeArguments == "dynamic" || typeArguments == "dynamic, dynamic")) {
    return;
  }

  if (!typeName.contains("<$typeArguments>")) {
    Expect.fail("Object should have had generic type '<$typeArguments>', "
        "but was '$typeName'.");
  }
}

void expectListOf<T>(Object object) {
  Expect.type<List>(object);
  _expectTypeArguments(T.toString(), object);
}

void expectSetOf<T>(Object object) {
  Expect.type<Set>(object);
  _expectTypeArguments(T.toString(), object);
}

void expectMapOf<K, V>(Object object) {
  Expect.type<Map>(object);
  _expectTypeArguments("$K, $V", object);
}
