// 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_test;

import 'dart:io';
import 'memory_compiler.dart';
import 'package:async_helper/async_helper.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';
import 'serialization_test_helper.dart';

main(List<String> arguments) {
  // Ensure that we can print out constant expressions.
  DEBUG_MODE = true;

  Uri entryPoint;
  String outPath;
  bool prettyPrint = false;
  for (String arg in arguments) {
    if (arg.startsWith('--')) {
      if (arg.startsWith('--out=')) {
        outPath = arg.substring('--out='.length);
      } else if (arg == '--pretty-print') {
        prettyPrint = true;
      } else {
        print("Unknown option $arg");
      }
    } else {
      if (entryPoint != null) {
        print("Multiple entrypoints is not supported.");
      }
      entryPoint = Uri.parse(arg);
    }
  }
  if (entryPoint == null) {
    entryPoint = Uri.parse('dart:core');
  }
  asyncTest(() async {
    CompilationResult result = await runCompiler(
        entryPoint: entryPoint, options: [Flags.analyzeAll]);
    Compiler compiler = result.compiler;
    testSerialization(compiler.libraryLoader.libraries,
                      outPath: outPath,
                      prettyPrint: prettyPrint);
  });
}

void testSerialization(Iterable<LibraryElement> libraries1,
                       {String outPath,
                        bool prettyPrint}) {
  Serializer serializer = new Serializer();
  for (LibraryElement library1 in libraries1) {
    serializer.serialize(library1);
  }
  String text = serializer.toText(const JsonSerializationEncoder());
  String outText = text;
  if (prettyPrint) {
    outText = serializer.prettyPrint();
  }
  if (outPath != null) {
    new File(outPath).writeAsStringSync(outText);
  } else if (prettyPrint) {
    print(outText);
  }

  Deserializer deserializer = new Deserializer.fromText(
      new DeserializationContext(),
      text, const JsonSerializationDecoder());
  List<LibraryElement> libraries2 = <LibraryElement>[];
  for (LibraryElement library1 in libraries1) {
    LibraryElement library2 =
        deserializer.lookupLibrary(library1.canonicalUri);
    if (library2 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    checkLibraryContent('library1', 'library2', 'library', library1, library2);
    libraries2.add(library2);
  }

  Serializer serializer2 = new Serializer();
  for (LibraryElement library2 in libraries2) {
    serializer2.serialize(library2);
  }
  String text2 = serializer2.toText(const JsonSerializationEncoder());

  Deserializer deserializer3 = new Deserializer.fromText(
      new DeserializationContext(),
      text2, const JsonSerializationDecoder());
  for (LibraryElement library1 in libraries1) {
    LibraryElement library2 =
        deserializer.lookupLibrary(library1.canonicalUri);
    if (library2 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    LibraryElement library3 =
        deserializer3.lookupLibrary(library1.canonicalUri);
    if (library3 == null) {
      throw new ArgumentError('No library ${library1.canonicalUri} found.');
    }
    checkLibraryContent('library1', 'library3', 'library', library1, library3);
    checkLibraryContent('library2', 'library3', 'library', library2, library3);
  }
}

/// Check the equivalence of [library1] and [library2] and their content.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkLibraryContent(
    Object object1, object2, String property,
    LibraryElement library1, LibraryElement library2) {
  checkElementProperties(object1, object2, property, library1, library2);
}

/// Check the equivalence of [element1] and [element2] and their properties.
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkElementProperties(
    Object object1, object2, String property,
    Element element1, Element element2) {
  const ElementPropertyEquivalence().visit(element1, element2);
}

/// Checks the equivalence of [constructor1] and [constructor2].
void constantConstructorEquivalence(ConstantConstructor constructor1,
                                    ConstantConstructor constructor2) {
  const ConstantConstructorEquivalence().visit(constructor1, constructor2);
}

/// Visitor that checks the equivalence of [ConstantConstructor]s.
class ConstantConstructorEquivalence
    extends ConstantConstructorVisitor<dynamic, ConstantConstructor> {
  const ConstantConstructorEquivalence();

  @override
  void visit(ConstantConstructor constructor1,
             ConstantConstructor constructor2) {
    if (identical(constructor1, constructor2)) return;
    check(constructor1, constructor2, 'kind',
          constructor1.kind, constructor2.kind);
    constructor1.accept(this, constructor2);
  }

  @override
  visitGenerative(
      GenerativeConstantConstructor constructor1,
      GenerativeConstantConstructor constructor2) {
    checkTypes(
        constructor1, constructor2, 'type',
        constructor1.type, constructor2.type);
    check(constructor1, constructor2, 'defaultValues.length',
          constructor1.defaultValues.length,
          constructor2.defaultValues.length);
    constructor1.defaultValues.forEach((k, v) {
      checkConstants(
          constructor1, constructor2, 'defaultValue[$k]',
          v, constructor2.defaultValues[k]);
    });
    check(constructor1, constructor2, 'fieldMap.length',
          constructor1.fieldMap.length,
          constructor2.fieldMap.length);
    constructor1.fieldMap.forEach((k1, v1) {
      bool matched = false;
      constructor2.fieldMap.forEach((k2, v2) {
        if (k1.name == k2.name &&
            k1.library.canonicalUri == k2.library.canonicalUri) {
          checkElementIdentities(
              constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2);
          checkConstants(
              constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2);
          matched = true;
        }
      });
      if (!matched) {
        throw 'Unmatched field $k1 = $v1';
      }
    });
    checkConstants(
        constructor1, constructor2, 'superConstructorInvocation',
        constructor1.superConstructorInvocation,
        constructor2.superConstructorInvocation);
  }

  @override
  visitRedirectingFactory(
      RedirectingFactoryConstantConstructor constructor1,
      RedirectingFactoryConstantConstructor constructor2) {
    checkConstants(
        constructor1, constructor2, 'targetConstructorInvocation',
        constructor1.targetConstructorInvocation,
        constructor2.targetConstructorInvocation);
  }

  @override
  visitRedirectingGenerative(
      RedirectingGenerativeConstantConstructor constructor1,
      RedirectingGenerativeConstantConstructor constructor2) {
    check(constructor1, constructor2, 'defaultValues.length',
          constructor1.defaultValues.length,
          constructor2.defaultValues.length);
    constructor1.defaultValues.forEach((k, v) {
      checkConstants(
          constructor1, constructor2, 'defaultValue[$k]',
          v, constructor2.defaultValues[k]);
    });
    checkConstants(
        constructor1, constructor2, 'thisConstructorInvocation',
        constructor1.thisConstructorInvocation,
        constructor2.thisConstructorInvocation);
  }
}

/// Check the equivalence of the two lists of elements, [list1] and [list2].
///
/// Uses [object1], [object2] and [property] to provide context for failures.
checkElementLists(Object object1, Object object2, String property,
                  Iterable<Element> list1, Iterable<Element> list2) {
  checkListEquivalence(object1, object2, property,
                  list1, list2, checkElementProperties);
}

/// Visitor that checks for equivalence of [Element] properties.
class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
  const ElementPropertyEquivalence();

  void visit(Element element1, Element element2) {
    if (element1 == null && element2 == null) return;
    element1 = element1.declaration;
    element2 = element2.declaration;
    if (element1 == element2) return;
    check(element1, element2, 'kind', element1.kind, element2.kind);
    element1.accept(this, element2);
  }

  @override
  void visitElement(Element e, Element arg) {
    throw new UnsupportedError("Unsupported element $e");
  }

  @override
  void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'libraryName',
          element1.libraryName, element2.libraryName);
    visitMembers(element1, element2);
    visit(element1.entryCompilationUnit, element2.entryCompilationUnit);

    checkElementLists(
        element1, element2, 'compilationUnits',
        LibrarySerializer.getCompilationUnits(element1),
        LibrarySerializer.getCompilationUnits(element2));

    checkElementListIdentities(
        element1, element2, 'imports',
        LibrarySerializer.getImports(element1),
        LibrarySerializer.getImports(element2));
    checkElementListIdentities(
        element1, element2, 'exports', element1.exports, element2.exports);

    checkElementListIdentities(
        element1, element2, 'importScope',
        LibrarySerializer.getImportedElements(element1),
        LibrarySerializer.getImportedElements(element2));

    checkElementListIdentities(
        element1, element2, 'exportScope',
        LibrarySerializer.getExportedElements(element1),
        LibrarySerializer.getExportedElements(element2));
  }

  @override
  void visitCompilationUnitElement(CompilationUnitElement element1,
                                   CompilationUnitElement element2) {
    check(element1, element2,
          'name',
          element1.name, element2.name);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    check(element1, element2,
          'script.resourceUri',
          element1.script.resourceUri, element2.script.resourceUri);
    List<Element> members1 = <Element>[];
    List<Element> members2 = <Element>[];
    element1.forEachLocalMember((Element member) {
      members1.add(member);
    });
    element2.forEachLocalMember((Element member) {
      members2.add(member);
    });
    checkElementListIdentities(
        element1, element2, 'localMembers', members1, members2);
  }

  void visitMembers(ScopeContainerElement element1,
                    ScopeContainerElement element2) {
    Set<String> names = new Set<String>();
    Iterable<Element> members1 = element1.isLibrary
        ? LibrarySerializer.getMembers(element1)
        : ClassSerializer.getMembers(element1);
    Iterable<Element> members2 = element2.isLibrary
        ? LibrarySerializer.getMembers(element2)
        : ClassSerializer.getMembers(element2);
    for (Element member in members1) {
      names.add(member.name);
    }
    for (Element member in members2) {
      names.add(member.name);
    }
    element1 = element1.implementation;
    element2 = element2.implementation;
    for (String name in names) {
      Element member1 = element1.localLookup(name);
      Element member2 = element2.localLookup(name);
      if (member1 == null) {
        String message =
            'Missing member for $member2 in\n ${members1.join('\n ')}';
        if (member2.isAbstractField) {
          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
          //print(message);
          continue;
        } else {
          throw message;
        }
      }
      if (member2 == null) {
        String message =
            'Missing member for $member1 in\n ${members2.join('\n ')}';
        if (member1.isAbstractField) {
          // TODO(johnniwinther): Ensure abstract fields are handled correctly.
          //print(message);
          continue;
        } else {
          throw message;
        }
      }
      //print('Checking member ${member1} against ${member2}');
      visit(member1, member2);
    }
  }

  @override
  void visitClassElement(ClassElement element1, ClassElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    check(element1, element2, 'isObject',
        element1.isObject, element2.isObject);
    checkTypeLists(element1, element2, 'typeVariables',
        element1.typeVariables, element2.typeVariables);
    check(element1, element2, 'isAbstract',
        element1.isAbstract, element2.isAbstract);
    check(element1, element2, 'isUnnamedMixinApplication',
        element1.isUnnamedMixinApplication, element2.isUnnamedMixinApplication);
    check(element1, element2, 'isEnumClass',
        element1.isEnumClass, element2.isEnumClass);
    if (element1.isEnumClass) {
      EnumClassElement enum1 = element1;
      EnumClassElement enum2 = element2;
      checkElementLists(enum1, enum2, 'enumValues',
                        enum1.enumValues, enum2.enumValues);
    }
    if (!element1.isObject) {
      checkTypes(element1, element2, 'supertype',
          element1.supertype, element2.supertype);
    }
    check(element1, element2, 'hierarchyDepth',
          element1.hierarchyDepth, element2.hierarchyDepth);
    checkTypeLists(
        element1, element2, 'allSupertypes',
        element1.allSupertypes.toList(),
        element2.allSupertypes.toList());
    OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
    OrderedTypeSet typeSet2 = element1.allSupertypesAndSelf;
    checkListEquivalence(
        element1, element2, 'allSupertypes',
        typeSet1.levelOffsets,
        typeSet2.levelOffsets,
        check);
    check(element1, element2, 'allSupertypesAndSelf.levels',
          typeSet1.levels, typeSet2.levels);
    checkTypeLists(
        element1, element2, 'supertypes',
        typeSet1.supertypes.toList(),
        typeSet2.supertypes.toList());
    checkTypeLists(
        element1, element2, 'types',
        typeSet1.types.toList(),
        typeSet2.types.toList());

    checkTypeLists(
        element1, element2, 'interfaces',
        element1.interfaces.toList(),
        element2.interfaces.toList());

    List<ConstructorElement> getConstructors(ClassElement cls) {
      return cls.implementation.constructors.map((c) => c.declaration).toList();
    }

    checkElementLists(
        element1, element2, 'constructors',
        getConstructors(element1),
        getConstructors(element2));

    visitMembers(element1, element2);
  }

  @override
  void visitFieldElement(FieldElement element1, FieldElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(element1, element2, 'isConst',
          element1.isConst, element2.isConst);
    check(element1, element2, 'isFinal',
          element1.isFinal, element2.isFinal);
    if (element1.isConst) {
      checkConstants(
          element1, element2, 'constant',
          element1.constant, element2.constant);
    }
    check(element1, element2, 'isTopLevel',
          element1.isTopLevel, element2.isTopLevel);
    check(element1, element2, 'isStatic',
          element1.isStatic, element2.isStatic);
    check(element1, element2, 'isInstanceMember',
          element1.isInstanceMember, element2.isInstanceMember);

    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
  }

  @override
  void visitFunctionElement(FunctionElement element1,
                            FunctionElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name',
          element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    checkListEquivalence(
        element1, element2, 'parameters',
        element1.parameters, element2.parameters,
        checkElementProperties);
    check(element1, element2, 'isOperator',
          element1.isOperator, element2.isOperator);

    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
  }

  @override
  void visitConstructorElement(ConstructorElement element1,
                               ConstructorElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    checkElementIdentities(
        element1, element2, 'enclosingClass',
        element1.enclosingClass, element2.enclosingClass);
    check(
        element1, element2, 'name',
        element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkListEquivalence(
        element1, element2, 'parameters',
        element1.parameters, element2.parameters,
        checkElementProperties);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(element1, element2, 'isConst',
          element1.isConst, element2.isConst);
    check(element1, element2, 'isExternal',
          element1.isExternal, element2.isExternal);
    if (element1.isConst && !element1.isExternal) {
      constantConstructorEquivalence(
          element1.constantConstructor,
          element2.constantConstructor);
    }
  }

  @override
  void visitAbstractFieldElement(AbstractFieldElement element1,
                                 AbstractFieldElement element2) {
    visit(element1.getter, element2.getter);
    visit(element1.setter, element2.setter);
  }

  @override
  void visitTypeVariableElement(TypeVariableElement element1,
                                TypeVariableElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    check(element1, element2, 'index', element1.index, element2.index);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    checkTypes(
        element1, element2, 'bound',
        element1.bound, element2.bound);
  }

  @override
  void visitTypedefElement(TypedefElement element1,
                           TypedefElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'alias',
        element1.alias, element2.alias);
    checkTypeLists(
        element1, element2, 'typeVariables',
        element1.typeVariables, element2.typeVariables);
    checkElementIdentities(
        element1, element2, 'library',
        element1.library, element2.library);
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
    // TODO(johnniwinther): Check the equivalence of typedef parameters.
  }

  @override
  void visitParameterElement(ParameterElement element1,
                             ParameterElement element2) {
    checkElementIdentities(null, null, null, element1, element2);
    checkElementIdentities(
        element1, element2, 'functionDeclaration',
        element1.functionDeclaration, element2.functionDeclaration);
    check(element1, element2, 'name', element1.name, element2.name);
    check(element1, element2, 'sourcePosition',
          element1.sourcePosition, element2.sourcePosition);
    checkTypes(
        element1, element2, 'type',
        element1.type, element2.type);
    check(
        element1, element2, 'isOptional',
        element1.isOptional, element2.isOptional);
    check(
        element1, element2, 'isNamed',
        element1.isNamed, element2.isNamed);
    check(element1, element2, 'name', element1.name, element2.name);
    if (element1.isOptional) {
      checkConstants(
          element1, element2, 'constant',
          element1.constant, element2.constant);
    }
    checkElementIdentities(
        element1, element2, 'compilationUnit',
        element1.compilationUnit, element2.compilationUnit);
  }

  @override
  void visitFieldParameterElement(InitializingFormalElement element1,
                                  InitializingFormalElement element2) {
    visitParameterElement(element1, element2);
    checkElementIdentities(
        element1, element2, 'fieldElement',
        element1.fieldElement, element2.fieldElement);
  }

  @override
  void visitImportElement(ImportElement element1, ImportElement element2) {
    check(element1, element2, 'uri', element1.uri, element2.uri);
    check(
        element1, element2, 'isDeferred',
        element1.isDeferred, element2.isDeferred);
    checkElementProperties(
        element1, element2, 'prefix',
        element1.prefix, element2.prefix);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.importedLibrary, element2.importedLibrary);
  }

  @override
  void visitExportElement(ExportElement element1, ExportElement element2) {
    check(element1, element2, 'uri', element1.uri, element2.uri);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.exportedLibrary, element2.exportedLibrary);
  }

  @override
  void visitPrefixElement(PrefixElement element1, PrefixElement element2) {
    check(
        element1, element2, 'isDeferred',
        element1.isDeferred, element2.isDeferred);
    checkElementIdentities(
        element1, element2, 'importedLibrary',
        element1.deferredImport, element2.deferredImport);
    // TODO(johnniwinther): Check members.
  }
}
