// 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 analyzer.test.src.summary.prelinker_test;

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/prelink.dart';
import 'package:unittest/unittest.dart';

import '../../reflective_tests.dart';
import 'summarize_elements_test.dart';
import 'summary_common.dart';

main() {
  groupSep = ' | ';
  runReflectiveTests(PrelinkerTest);
}

/**
 * Override of [SummaryTest] which verifies the correctness of the prelinker by
 * creating summaries from the element model, discarding their prelinked
 * information, and then recreating it using the prelinker.
 */
@reflectiveTest
class PrelinkerTest extends SummarizeElementsTest {
  final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
      <String, UnlinkedPublicNamespace>{};

  @override
  bool get expectAbsoluteUrisInDependencies => false;

  @override
  bool get skipFullyLinkedData => true;

  @override
  bool get strongMode => false;

  @override
  Source addNamedSource(String filePath, String contents) {
    Source source = super.addNamedSource(filePath, contents);
    uriToPublicNamespace[absUri(filePath)] =
        computePublicNamespaceFromText(contents, source);
    return source;
  }

  String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
    Source resolvedSource =
        analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
    if (resolvedSource == null) {
      fail('Failed to resolve relative uri "$relativeUri"');
    }
    return resolvedSource.uri.toString();
  }

  @override
  void serializeLibraryElement(LibraryElement library) {
    super.serializeLibraryElement(library);
    Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
    expect(unlinkedUnits.length, unitUris.length);
    for (int i = 1; i < unlinkedUnits.length; i++) {
      uriToUnit[unitUris[i]] = unlinkedUnits[i];
    }
    UnlinkedUnit getPart(String relativeUri) {
      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
      UnlinkedUnit unit = uriToUnit[absoluteUri];
      if (unit == null) {
        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
            ' (resolves to "$absoluteUri").');
      }
      return unit;
    }
    UnlinkedPublicNamespace getImport(String relativeUri) {
      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
      UnlinkedPublicNamespace namespace = SerializedMockSdk
          .instance.uriToUnlinkedUnit[absoluteUri]?.publicNamespace;
      if (namespace == null) {
        namespace = uriToPublicNamespace[absoluteUri];
      }
      if (namespace == null && !allowMissingFiles) {
        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
            ' (resolves to "$absoluteUri").'
            '  Namespaces available: ${uriToPublicNamespace.keys}');
      }
      return namespace;
    }
    linked = new LinkedLibrary.fromBuffer(
        prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
    validateLinkedLibrary(linked);
  }
}
