// 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.

@deprecated
library analyzer.test.source.embedder_test;

import 'dart:core';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../embedder_tests.dart';
import '../resource_utils.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(DartUriResolverTest);
    defineReflectiveTests(EmbedderSdkTest);
    defineReflectiveTests(EmbedderUriResolverTest);
  });
}

@reflectiveTest
class DartUriResolverTest extends EmbedderRelatedTest {
  void test_embedderYaml() {
    EmbedderYamlLocator locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    EmbedderSdk sdk = EmbedderSdk(locator.embedderYamls);
    DartUriResolver resolver = DartUriResolver(sdk);

    void expectResolved(dartUri, posixPath) {
      Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
      expect(source, isNotNull, reason: dartUri);
      expect(source.fullName, posixToOSPath(posixPath));
    }

    // Check that they map to the correct paths.
    expectResolved('dart:core', '$foxLib/core/core.dart');
    expectResolved('dart:fox', '$foxLib/slippy.dart');
    expectResolved('dart:bear', '$foxLib/grizzly.dart');
    expectResolved('dart:relative', '$foxPath/relative.dart');
    expectResolved('dart:deep', '$foxLib/deep/directory/file.dart');
  }
}

@reflectiveTest
class EmbedderSdkTest extends EmbedderRelatedTest {
  void test_creation() {
    EmbedderYamlLocator locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    EmbedderSdk sdk = EmbedderSdk(locator.embedderYamls);

    expect(sdk.urlMappings, hasLength(5));
  }

  void test_fromFileUri() {
    EmbedderYamlLocator locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    EmbedderSdk sdk = EmbedderSdk(locator.embedderYamls);

    expectSource(String posixPath, String dartUri) {
      Uri uri = Uri.parse(posixToOSFileUri(posixPath));
      Source source = sdk.fromFileUri(uri);
      expect(source, isNotNull, reason: posixPath);
      expect(source.uri.toString(), dartUri);
      expect(source.fullName, posixToOSPath(posixPath));
    }

    expectSource('$foxLib/slippy.dart', 'dart:fox');
    expectSource('$foxLib/deep/directory/file.dart', 'dart:deep');
    expectSource('$foxLib/deep/directory/part.dart', 'dart:deep/part.dart');
  }

  void test_getSdkLibrary() {
    EmbedderYamlLocator locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    EmbedderSdk sdk = EmbedderSdk(locator.embedderYamls);

    SdkLibrary lib = sdk.getSdkLibrary('dart:fox');
    expect(lib, isNotNull);
    expect(lib.path, posixToOSPath('$foxLib/slippy.dart'));
    expect(lib.shortName, 'dart:fox');
  }

  void test_mapDartUri() {
    EmbedderYamlLocator locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    EmbedderSdk sdk = EmbedderSdk(locator.embedderYamls);

    void expectSource(String dartUri, String posixPath) {
      Source source = sdk.mapDartUri(dartUri);
      expect(source, isNotNull, reason: posixPath);
      expect(source.uri.toString(), dartUri);
      expect(source.fullName, posixToOSPath(posixPath));
    }

    expectSource('dart:core', '$foxLib/core/core.dart');
    expectSource('dart:fox', '$foxLib/slippy.dart');
    expectSource('dart:deep', '$foxLib/deep/directory/file.dart');
    expectSource('dart:deep/part.dart', '$foxLib/deep/directory/part.dart');
  }
}

@reflectiveTest
class EmbedderUriResolverTest extends EmbedderRelatedTest {
  void test_embedderYaml() {
    var locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    var resolver = EmbedderUriResolver(locator.embedderYamls);

    expectResolved(dartUri, posixPath) {
      Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
      expect(source, isNotNull, reason: dartUri);
      expect(source.fullName, posixToOSPath(posixPath));
    }

    // We have five mappings.
    expect(resolver, hasLength(5));
    // Check that they map to the correct paths.
    expectResolved('dart:core', '$foxLib/core/core.dart');
    expectResolved('dart:fox', '$foxLib/slippy.dart');
    expectResolved('dart:bear', '$foxLib/grizzly.dart');
    expectResolved('dart:relative', '$foxPath/relative.dart');
    expectResolved('dart:deep', '$foxLib/deep/directory/file.dart');
  }

  void test_nullEmbedderYamls() {
    var resolver = EmbedderUriResolver(null);
    expect(resolver, hasLength(0));
  }

  void test_restoreAbsolute() {
    var locator = EmbedderYamlLocator({
      'fox': <Folder>[pathTranslator.getResource(foxLib)]
    });
    var resolver = EmbedderUriResolver(locator.embedderYamls);

    expectRestore(String dartUri, [String expected]) {
      var parsedUri = Uri.parse(dartUri);
      var source = resolver.resolveAbsolute(parsedUri);
      expect(source, isNotNull);
      // Restore source's uri.
      var restoreUri = resolver.restoreAbsolute(source);
      expect(restoreUri, isNotNull, reason: dartUri);
      // Verify that it is 'dart:fox'.
      expect(restoreUri.toString(), expected ?? dartUri);
      List<String> split = (expected ?? dartUri).split(':');
      expect(restoreUri.scheme, split[0]);
      expect(restoreUri.path, split[1]);
    }

    expectRestore('dart:deep');
    expectRestore('dart:deep/file.dart', 'dart:deep');
    expectRestore('dart:deep/part.dart');
    expectRestore('dart:deep/deep/file.dart');
  }
}
