// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:collection';

import 'package:collection/collection.dart';
import 'package:yaml/yaml.dart';

/// Creates a map that uses our custom [deepEquals] and [deepHashCode] functions
/// to determine equality.
Map<K, V> deepEqualsMap<K, V>() =>
    LinkedHashMap(equals: deepEquals, hashCode: deepHashCode);

/// Compares two [Object]s for deep equality. This implementation differs from
/// `package:yaml`'s deep equality notation by allowing for comparison of
/// non-scalar map keys.
bool deepEquals(dynamic obj1, dynamic obj2) {
  if (obj1 is YamlNode) obj1 = obj1.value;
  if (obj2 is YamlNode) obj2 = obj2.value;

  if (obj1 is Map && obj2 is Map) {
    return mapDeepEquals(obj1, obj2);
  }

  if (obj1 is List && obj2 is List) {
    return listDeepEquals(obj1, obj2);
  }

  return obj1 == obj2;
}

/// Compares two [List]s for deep equality.
bool listDeepEquals(List list1, List list2) {
  if (list1.length != list2.length) return false;

  if (list1 is YamlList) list1 = list1.nodes;
  if (list2 is YamlList) list2 = list2.nodes;

  for (var i = 0; i < list1.length; i++) {
    if (!deepEquals(list1[i], list2[i])) {
      return false;
    }
  }

  return true;
}

/// Compares two [Map]s for deep equality. Differs from `package:yaml`'s deep
/// equality notation by allowing for comparison of non-scalar map keys.
bool mapDeepEquals(Map map1, Map map2) {
  if (map1.length != map2.length) return false;

  if (map1 is YamlList) map1 = (map1 as YamlMap).nodes;
  if (map2 is YamlList) map2 = (map2 as YamlMap).nodes;

  return map1.keys.every((key) {
    if (!containsKey(map2, key)) return false;

    /// Because two keys may be equal by deep equality but using one key on the
    /// other map might not get a hit since they may not be both using our
    /// [deepEqualsMap].
    final key2 = getKey(map2, key);

    if (!deepEquals(map1[key], map2[key2])) {
      return false;
    }

    return true;
  });
}

/// Returns a hashcode for [value] such that structures that are equal by
/// [deepEquals] will have the same hash code.
int deepHashCode(Object? value) {
  if (value is Map) {
    const equality = UnorderedIterableEquality();
    return equality.hash(value.keys.map(deepHashCode)) ^
        equality.hash(value.values.map(deepHashCode));
  } else if (value is Iterable) {
    return const IterableEquality().hash(value.map(deepHashCode));
  } else if (value is YamlScalar) {
    return value.value.hashCode;
  }

  return value.hashCode;
}

/// Returns the [YamlNode] corresponding to the provided [key].
YamlNode getKeyNode(YamlMap map, Object? key) {
  return map.nodes.keys.firstWhere((node) => deepEquals(node, key)) as YamlNode;
}

/// Returns the [YamlNode] after the [YamlNode] corresponding to the provided
/// [key].
YamlNode? getNextKeyNode(YamlMap map, Object? key) {
  final keyIterator = map.nodes.keys.iterator;
  while (keyIterator.moveNext()) {
    if (deepEquals(keyIterator.current, key) && keyIterator.moveNext()) {
      return keyIterator.current;
    }
  }

  return null;
}

/// Returns the key in [map] that is equal to the provided [key] by the notion
/// of deep equality.
Object? getKey(Map map, Object? key) {
  return map.keys.firstWhere((k) => deepEquals(k, key));
}

/// Checks if [map] has any keys equal to the provided [key] by deep equality.
bool containsKey(Map map, Object? key) {
  return map.keys.where((node) => deepEquals(node, key)).isNotEmpty;
}
