// Copyright (c) 2015, 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_model_test;

import 'dart:async';
import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/backend_api.dart';
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/serialization/element_serialization.dart';
import 'package:compiler/src/serialization/impact_serialization.dart';
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/serialization/task.dart';
import 'package:compiler/src/universe/world_impact.dart';
import 'package:compiler/src/universe/class_set.dart';
import 'package:compiler/src/universe/use.dart';
import 'memory_compiler.dart';
import 'serialization_helper.dart';
import 'serialization_analysis_test.dart';
import 'serialization_impact_test.dart';
import 'serialization_test.dart';

main(List<String> arguments) {
  String filename;
  for (String arg in arguments) {
    if (!arg.startsWith('-')) {
      filename = arg;
    }
  }
  bool verbose = arguments.contains('-v');

  asyncTest(() async {
    print('------------------------------------------------------------------');
    print('serialize dart:core');
    print('------------------------------------------------------------------');
    String serializedData;
    File file = new File('out.data');
    if (arguments.contains('-l')) {
      if (file.existsSync()) {
        print('Loading data from $file');
        serializedData = file.readAsStringSync();
      }
    }
    if (serializedData == null) {
      serializedData = await serializeDartCore();
      if (arguments.contains('-s')) {
        print('Saving data to $file');
        file.writeAsStringSync(serializedData);
      }
    }
    if (filename != null) {
      Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename));
      await check(serializedData, entryPoint);
    } else {
      Uri entryPoint = Uri.parse('memory:main.dart');
      for (Test test in TESTS) {
        if (test.sourceFiles['main.dart']
                .contains('main(List<String> arguments)')) {
          // TODO(johnniwinther): Check this test.
          continue;
        }
        print('==============================================================');
        print(test.sourceFiles);
        await check(
          serializedData,
          entryPoint,
          sourceFiles: test.sourceFiles,
          verbose: verbose);
      }
    }
  });
}

Future check(
  String serializedData,
  Uri entryPoint,
  {Map<String, String> sourceFiles: const <String, String>{},
   bool verbose: false}) async {

  print('------------------------------------------------------------------');
  print('compile normal');
  print('------------------------------------------------------------------');
  Compiler compilerNormal = compilerFor(
      memorySourceFiles: sourceFiles,
      options: [Flags.analyzeOnly]);
  compilerNormal.resolution.retainCachesForTesting = true;
  await compilerNormal.run(entryPoint);
  compilerNormal.world.populate();

  print('------------------------------------------------------------------');
  print('compile deserialized');
  print('------------------------------------------------------------------');
  Compiler compilerDeserialized = compilerFor(
      memorySourceFiles: sourceFiles,
      options: [Flags.analyzeOnly]);
  compilerDeserialized.resolution.retainCachesForTesting = true;
  deserialize(compilerDeserialized, serializedData);
  await compilerDeserialized.run(entryPoint);
  compilerDeserialized.world.populate();

  checkResolutionImpacts(
      compilerNormal, compilerDeserialized,
      verbose: verbose);

  checkSets(
      compilerNormal.resolverWorld.directlyInstantiatedClasses,
      compilerDeserialized.resolverWorld.directlyInstantiatedClasses,
      "Directly instantiated classes mismatch",
      areElementsEquivalent,
      verbose: verbose);

  checkSets(
      compilerNormal.resolverWorld.instantiatedTypes,
      compilerDeserialized.resolverWorld.instantiatedTypes,
      "Instantiated types mismatch",
      areTypesEquivalent,
      // TODO(johnniwinther): Ensure that all instantiated types are tracked.
      failOnUnfound: false,
      verbose: verbose);

  checkSets(
      compilerNormal.resolverWorld.isChecks,
      compilerDeserialized.resolverWorld.isChecks,
      "Is-check mismatch",
      areTypesEquivalent,
      verbose: verbose);

  checkSets(
      compilerNormal.enqueuer.resolution.processedElements,
      compilerDeserialized.enqueuer.resolution.processedElements,
      "Processed element mismatch",
      areElementsEquivalent,
      verbose: verbose);

  checkClassHierarchyNodes(
    compilerNormal.world.getClassHierarchyNode(
        compilerNormal.coreClasses.objectClass),
    compilerDeserialized.world.getClassHierarchyNode(
        compilerDeserialized.coreClasses.objectClass),
    verbose: verbose);
}

void checkClassHierarchyNodes(
    ClassHierarchyNode a, ClassHierarchyNode b,
    {bool verbose: false}) {
  if (verbose) {
    print('Checking $a vs $b');
  }
  Expect.isTrue(
      areElementsEquivalent(a.cls, b.cls),
      "Element identity mismatch for ${a.cls} vs ${b.cls}.");
  Expect.equals(
      a.isDirectlyInstantiated,
      b.isDirectlyInstantiated,
      "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}.");
  Expect.equals(
      a.isIndirectlyInstantiated,
      b.isIndirectlyInstantiated,
      "Value mismatch for 'isIndirectlyInstantiated' "
      "for ${a.cls} vs ${b.cls}.");
  // TODO(johnniwinther): Enforce a canonical and stable order on direct
  // subclasses.
  for (ClassHierarchyNode child in a.directSubclasses) {
    bool found = false;
    for (ClassHierarchyNode other in b.directSubclasses) {
      if (areElementsEquivalent(child.cls, other.cls)) {
        checkClassHierarchyNodes(child, other,
            verbose: verbose);
        found = true;
        break;
      }
    }
    if (!found) {
      Expect.isFalse(
          child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}');
    }
  }
}

void checkSets(
    Iterable set1,
    Iterable set2,
    String messagePrefix,
    bool areEquivalent(a, b),
    {bool failOnUnfound: true,
     bool verbose: false}) {
  List common = [];
  List unfound = [];
  Set remaining = computeSetDifference(
      set1, set2, common, unfound, areEquivalent);
  StringBuffer sb = new StringBuffer();
  sb.write("$messagePrefix:");
  if (verbose) {
    sb.write("\n Common:\n  ${common.join('\n  ')}");
  }
  if (unfound.isNotEmpty || verbose) {
    sb.write("\n Unfound:\n  ${unfound.join('\n  ')}");
  }
  if (remaining.isNotEmpty || verbose) {
    sb.write("\n Extra: \n  ${remaining.join('\n  ')}");
  }
  String message = sb.toString();
  if (unfound.isNotEmpty || remaining.isNotEmpty) {

    if (failOnUnfound || remaining.isNotEmpty) {
      Expect.fail(message);
    } else {
      print(message);
    }
  } else if (verbose) {
    print(message);
  }
}
