// Copyright (c) 2016, 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.

library dart2js.serialization_test_helper;

import 'dart:io';
import 'memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/constants/constructors.dart';
import 'package:compiler/src/constants/expressions.dart';
import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/invariant.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/visitor.dart';
import 'package:compiler/src/ordered_typeset.dart';
import 'package:compiler/src/serialization/element_serialization.dart';
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';


/// Strategy for checking equivalence.
///
/// Use this strategy to fail early with contextual information in the event of
/// inequivalence.
class CheckStrategy implements TestStrategy {
  const CheckStrategy();

  @override
  bool test(var object1, var object2, String property, var value1, var value2,
            [bool equivalence(a, b) = equality]) {
    return check(object1, object2, property, value1, value2, equivalence);
  }

  @override
  bool testLists(
      Object object1, Object object2, String property,
      List list1, List list2,
      [bool elementEquivalence(a, b) = equality]) {
    return checkListEquivalence(
        object1, object2, property, list1, list2,
        (o1, o2, p, v1, v2) {
          if (!elementEquivalence(v1, v2)) {
            throw "$o1.$p = '${v1}' <> "
                  "$o2.$p = '${v2}'";
          }
          return true;
        });
  }

  @override
  bool testSets(
      var object1, var object2, String property,
      Iterable set1, Iterable set2,
      [bool elementEquivalence(a, b) = equality]) {
    return checkSetEquivalence(
        object1, object2,property, set1, set2, elementEquivalence);
  }

  @override
  bool testElements(
      Object object1, Object object2, String property,
      Element element1, Element element2) {
    return checkElementIdentities(
        object1, object2, property, element1, element2);
  }

  @override
  bool testTypes(
      Object object1, Object object2, String property,
      DartType type1, DartType type2) {
    return checkTypes(object1, object2, property, type1, type2);
  }

  @override
  bool testConstants(
      Object object1, Object object2, String property,
      ConstantExpression exp1, ConstantExpression exp2) {
    return checkConstants(object1, object2, property, exp1, exp2);
  }

  @override
  bool testTypeLists(
      Object object1, Object object2, String property,
      List<DartType> list1, List<DartType> list2) {
    return checkTypeLists(object1, object2, property, list1, list2);
  }

  @override
  bool testConstantLists(
      Object object1, Object object2, String property,
      List<ConstantExpression> list1,
      List<ConstantExpression> list2) {
    return checkConstantLists(object1, object2, property, list1, list2);
  }
}

/// Check that the values [property] of [object1] and [object2], [value1] and
/// [value2] respectively, are equal and throw otherwise.
bool check(var object1, var object2, String property, var value1, var value2,
           [bool equivalence(a, b) = equality]) {
  if (!equivalence(value1, value2)) {
    throw "property='$property' "
          "object1=$object1 (${object1.runtimeType}), value='${value1}' <> "
          "object2=$object2 (${object2.runtimeType}), value='${value2}'";
  }
  return true;
}

/// Check equivalence of the two lists, [list1] and [list2], using
/// [checkEquivalence] to check the pair-wise equivalence.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkListEquivalence(
    Object object1, Object object2, String property,
    Iterable list1, Iterable list2,
    void checkEquivalence(o1, o2, property, a, b)) {
  for (int i = 0; i < list1.length && i < list2.length; i++) {
    checkEquivalence(
        object1, object2, property,
        list1.elementAt(i), list2.elementAt(i));
  }
  for (int i = list1.length; i < list2.length; i++) {
    throw
        'Missing equivalent for element '
        '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n'
        '`${property}` on $object1:\n ${list1.join('\n ')}\n'
        '`${property}` on $object2:\n ${list2.join('\n ')}';
  }
  for (int i = list2.length; i < list1.length; i++) {
    throw
        'Missing equivalent for element '
        '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n'
        '`${property}` on $object1:\n ${list1.join('\n ')}\n'
        '`${property}` on $object2:\n ${list2.join('\n ')}';
  }
  return true;
}

/// Computes the set difference between [set1] and [set2] using
/// [elementEquivalence] to determine element equivalence.
///
/// Elements both in [set1] and [set2] are added to [common], elements in [set1]
/// but not in [set2] are added to [unfound], and the set of elements in [set2]
/// but not in [set1] are returned.
Set computeSetDifference(
    Iterable set1,
    Iterable set2,
    List common,
    List unfound,
    [bool sameElement(a, b) = equality]) {
  // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
  // - convert each set to a list and sort it first, then compare by walking
  // both lists in parallel
  // - map each element to a canonical object, create a map containing those
  // mappings, use the mapped sets to compare (then operations like
  // set.difference would work)
  Set remaining = set2.toSet();
  for (var element1 in set1) {
    bool found = false;
    for (var element2 in remaining) {
      if (sameElement(element1, element2)) {
        found = true;
        remaining.remove(element2);
        break;
      }
    }
    if (found) {
      common.add(element1);
    } else {
      unfound.add(element1);
    }
  }
  return remaining;
}

/// Check equivalence of the two iterables, [set1] and [set1], as sets using
/// [elementEquivalence] to compute the pair-wise equivalence.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkSetEquivalence(
    var object1,
    var object2,
    String property,
    Iterable set1,
    Iterable set2,
    bool sameElement(a, b)) {
  List common = [];
  List unfound = [];
  Set remaining =
      computeSetDifference(set1, set2, common, unfound, sameElement);
  if (unfound.isNotEmpty || remaining.isNotEmpty) {
    String message =
        "Set mismatch for `$property` on $object1 vs $object2: \n"
        "Common:\n ${common.join('\n ')}\n"
        "Unfound:\n ${unfound.join('\n ')}\n"
        "Extra: \n ${remaining.join('\n ')}";
    throw message;
  }
  return true;
}

/// Checks the equivalence of the identity (but not properties) of [element1]
/// and [element2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkElementIdentities(
    Object object1, Object object2, String property,
    Element element1, Element element2) {
  if (identical(element1, element2)) return true;
  if (element1 == null || element2 == null) {
    return check(object1, object2, property, element1, element2);
  } else {
    return const ElementIdentityEquivalence(const CheckStrategy())
        .visit(element1, element2);
  }
}

/// Checks the pair-wise equivalence of the identity (but not properties) of the
/// elements in [list] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkElementListIdentities(
    Object object1, Object object2, String property,
    Iterable<Element> list1, Iterable<Element> list2) {
  return checkListEquivalence(
      object1, object2, property,
      list1, list2, checkElementIdentities);
}

/// Checks the equivalence of [type1] and [type2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkTypes(
    Object object1, Object object2, String property,
    DartType type1, DartType type2) {
  if (identical(type1, type2)) return true;
  if (type1 == null || type2 == null) {
    return check(object1, object2, property, type1, type2);
  } else {
    return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
  }
}

/// Checks the pair-wise equivalence of the types in [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkTypeLists(
    Object object1, Object object2, String property,
    List<DartType> list1, List<DartType> list2) {
  return checkListEquivalence(
      object1, object2, property, list1, list2, checkTypes);
}

/// Checks the equivalence of [exp1] and [exp2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkConstants(
    Object object1, Object object2, String property,
    ConstantExpression exp1, ConstantExpression exp2) {
  if (identical(exp1, exp2)) return true;
  if (exp1 == null || exp2 == null) {
    return check(object1, object2, property, exp1, exp2);
  } else {
    return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
  }
}

/// Checks the pair-wise equivalence of the contants in [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
bool checkConstantLists(
    Object object1, Object object2, String property,
    List<ConstantExpression> list1,
    List<ConstantExpression> list2) {
  return checkListEquivalence(
      object1, object2, property,
      list1, list2, checkConstants);
}


/// Check member property equivalence between all members common to [compiler1]
/// and [compiler2].
void checkLoadedLibraryMembers(
    Compiler compiler1,
    Compiler compiler2,
    bool hasProperty(Element member1),
    void checkMemberProperties(Compiler compiler1, Element member1,
                               Compiler compiler2, Element member2,
                               {bool verbose}),
    {bool verbose: false}) {

  void checkMembers(Element member1, Element member2) {
    if (member1.isClass && member2.isClass) {
      ClassElement class1 = member1;
      ClassElement class2 = member2;
      class1.forEachLocalMember((m1) {
        checkMembers(m1, class2.lookupLocalMember(m1.name));
      });
      return;
    }

    if (!hasProperty(member1)) {
      return;
    }

    if (member2 == null) {
      return;
    }

    if (areElementsEquivalent(member1, member2)) {
      checkMemberProperties(
          compiler1, member1,
          compiler2, member2,
          verbose: verbose);
    }
  }

  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
    LibraryElement library2 =
        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
    if (library2 != null) {
      library1.forEachLocalMember((Element member1) {
        checkMembers(member1, library2.localLookup(member1.name));
      });

    }
  }
}

/// Check equivalence of all resolution impacts.
void checkAllImpacts(
    Compiler compiler1,
    Compiler compiler2,
    {bool verbose: false}) {
  checkLoadedLibraryMembers(
      compiler1,
      compiler2,
      (Element member1) {
        return compiler1.resolution.hasResolutionImpact(member1);
      },
      checkImpacts,
      verbose: true);
}

/// Check equivalence of resolution impact for [member1] and [member2].
void checkImpacts(Compiler compiler1, Element member1,
                  Compiler compiler2, Element member2,
                  {bool verbose: false}) {
  ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
  ResolutionImpact impact2 =
      compiler2.serialization.deserializer.getResolutionImpact(member2);

  if (impact1 == null || impact2 == null) return;

  if (verbose) {
    print('Checking impacts for $member1 vs $member2');
  }

  testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy());
}
