// 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/common.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 '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);
    check(element1, element2, 'isSynthesized',
        element1.isSynthesized, element2.isSynthesized);
  }

  @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;
        }
      }
      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);
    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);
    check(
        element1, element2, 'asyncMarker',
        element1.asyncMarker,
        element2.asyncMarker);

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

    check(
        element1, element2, 'functionSignature.type',
        element1.functionSignature.type,
        element2.functionSignature.type,
        areTypesEquivalent);
    checkElementLists(
        element1, element2, 'functionSignature.requiredParameters',
        element1.functionSignature.requiredParameters,
        element2.functionSignature.requiredParameters);
    checkElementLists(
        element1, element2, 'functionSignature.optionalParameters',
        element1.functionSignature.optionalParameters,
        element2.functionSignature.optionalParameters);
    check(
        element1, element2, 'functionSignature.requiredParameterCount',
        element1.functionSignature.requiredParameterCount,
        element2.functionSignature.requiredParameterCount);
    check(
        element1, element2, 'functionSignature.optionalParameterCount',
        element1.functionSignature.optionalParameterCount,
        element2.functionSignature.optionalParameterCount);
    check(
        element1, element2, 'functionSignature.optionalParametersAreNamed',
        element1.functionSignature.optionalParametersAreNamed,
        element2.functionSignature.optionalParametersAreNamed);
    check(
        element1, element2, 'functionSignature.hasOptionalParameters',
        element1.functionSignature.hasOptionalParameters,
        element2.functionSignature.hasOptionalParameters);
    check(
        element1, element2, 'functionSignature.parameterCount',
        element1.functionSignature.parameterCount,
        element2.functionSignature.parameterCount);
    checkElementLists(
        element1, element2, 'functionSignature.orderedOptionalParameters',
        element1.functionSignature.orderedOptionalParameters,
        element2.functionSignature.orderedOptionalParameters);
  }

  @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);
    }
    check(element1, element2, 'isRedirectingGenerative',
        element1.isRedirectingGenerative, element2.isRedirectingGenerative);
    check(element1, element2, 'isRedirectingFactory',
        element1.isRedirectingFactory, element2.isRedirectingFactory);
    checkElementIdentities(element1, element2, 'effectiveTarget',
        element1.effectiveTarget, element2.effectiveTarget);
    checkElementIdentities(element1, element2, 'definingConstructor',
        element1.definingConstructor, element2.definingConstructor);
    check(
        element1, element2, 'effectiveTargetType',
        element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
        element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
        areTypesEquivalent);
    checkElementIdentities(element1, element2, 'immediateRedirectionTarget',
        element1.immediateRedirectionTarget,
        element2.immediateRedirectionTarget);
    checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
        element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix);
  }

  @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, 'isFinal',
        element1.isFinal, element2.isFinal);
    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.
  }
}
