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

import 'dart:convert';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine, Logger;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgfile show parse;
import 'package:package_config/src/packages_impl.dart';
import 'package:path/path.dart' as pathos;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'test_support.dart';

main() {
  runPackageMapTests();
  defineReflectiveSuite(() {
    defineReflectiveTests(SourceFactoryTest);
  });
}

Source createSource({String path, String uri}) =>
    //TODO(pquitslund): find some way to pass an actual URI into source creation
    new MemoryResourceProvider()
        .getFile(path)
        .createSource(uri != null ? Uri.parse(uri) : null);

void runPackageMapTests() {
  MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
  final Uri baseUri = new Uri.file('test/base');
  final List<UriResolver> testResolvers = [
    new ResourceUriResolver(resourceProvider)
  ];

  Packages createPackageMap(Uri base, String configFileContents) {
    List<int> bytes = utf8.encode(configFileContents);
    Map<String, Uri> map = pkgfile.parse(bytes, base);
    return new MapPackages(map);
  }

  Map<String, List<Folder>> getPackageMap(String config) {
    Packages packages = createPackageMap(baseUri, config);
    SourceFactory factory = new SourceFactory(testResolvers, packages);
    return factory.packageMap;
  }

  String resolvePackageUri(
      {String uri,
      String config,
      Source containingSource,
      UriResolver customResolver}) {
    Packages packages = createPackageMap(baseUri, config);
    List<UriResolver> resolvers = testResolvers.toList();
    if (customResolver != null) {
      resolvers.add(customResolver);
    }
    SourceFactory factory = new SourceFactory(resolvers, packages);

    expect(AnalysisEngine.instance.logger, Logger.NULL);
    var logger = new TestLogger();
    AnalysisEngine.instance.logger = logger;
    try {
      Source source = factory.resolveUri(containingSource, uri);
      expect(logger.log, []);
      return source != null ? source.fullName : null;
    } finally {
      AnalysisEngine.instance.logger = Logger.NULL;
    }
  }

  Uri restorePackageUri(
      {Source source, String config, UriResolver customResolver}) {
    Packages packages = createPackageMap(baseUri, config);
    List<UriResolver> resolvers = testResolvers.toList();
    if (customResolver != null) {
      resolvers.add(customResolver);
    }
    SourceFactory factory = new SourceFactory(resolvers, packages);
    return factory.restoreUri(source);
  }

  String _p(String path) => resourceProvider.convertPath(path);

  Uri _u(String path) => resourceProvider.pathContext.toUri(_p(path));

  group('SourceFactoryTest', () {
    group('package mapping', () {
      group('resolveUri', () {
        test('URI in mapping', () {
          String uri = resolvePackageUri(config: '''
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
''', uri: 'package:unittest/unittest.dart');
          expect(
              uri,
              equals(_p(
                  '/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart')));
        });
        test('URI not in mapping', () {
          String uri = resolvePackageUri(config: '''
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
''', uri: 'package:foo/foo.dart');
          expect(uri, isNull);
        });
        test('Non-package URI', () {
          var testResolver = new CustomUriResolver(uriPath: _p('/test.dart'));
          String uri = resolvePackageUri(config: '''
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
''', uri: 'custom:custom.dart', customResolver: testResolver);
          expect(uri, testResolver.uriPath);
        });
        test('Bad package URI', () {
          String uri = resolvePackageUri(config: '', uri: 'package:foo');
          expect(uri, isNull);
        });
        test('Invalid URI', () {
          // TODO(pquitslund): fix clients to handle errors appropriately
          //   CLI: print message 'invalid package file format'
          //   SERVER: best case tell user somehow and recover...
          expect(
              () => resolvePackageUri(
                  config: 'foo:<:&%>', uri: 'package:foo/bar.dart'),
              throwsA(new TypeMatcher<FormatException>()));
        });
        test('Valid URI that cannot be further resolved', () {
          String uri = resolvePackageUri(
              config: 'foo:http://www.google.com', uri: 'package:foo/bar.dart');
          expect(uri, isNull);
        });
        test('Relative URIs', () {
          Source containingSource = createSource(
              path: _p('/foo/bar/baz/foo.dart'), uri: 'package:foo/foo.dart');
          String uri = resolvePackageUri(
              config: 'foo:${_u('/foo/bar/baz')}',
              uri: 'bar.dart',
              containingSource: containingSource);
          expect(uri, isNotNull);
          expect(uri, equals(_p('/foo/bar/baz/bar.dart')));
        });
      });
      group('restoreUri', () {
        test('URI in mapping', () {
          Uri uri = restorePackageUri(
              config: '''
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
''',
              source: new FileSource(resourceProvider.getFile(_p(
                  '/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart'))));
          expect(uri, isNotNull);
          expect(uri.toString(), equals('package:unittest/unittest.dart'));
        });
      });
      group('packageMap', () {
        test('non-file URIs filtered', () {
          Map<String, List<Folder>> map = getPackageMap('''
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
foo:http://www.google.com
''');
          expect(map.keys, unorderedEquals(['quiver']));
        });
      });
    });
  });

  group('URI utils', () {
    group('URI', () {
      test('startsWith', () {
        expect(utils.startsWith(Uri.parse('/foo/bar/'), Uri.parse('/foo/')),
            isTrue);
        expect(utils.startsWith(Uri.parse('/foo/bar/'), Uri.parse('/foo/bar/')),
            isTrue);
        expect(utils.startsWith(Uri.parse('/foo/bar'), Uri.parse('/foo/b')),
            isFalse);
        // Handle odd URIs (https://github.com/dart-lang/sdk/issues/24126)
        expect(utils.startsWith(Uri.parse('/foo/bar'), Uri.parse('')), isFalse);
        expect(utils.startsWith(Uri.parse(''), Uri.parse('/foo/bar')), isFalse);
      });
    });
  });
}

class AbsoluteUriResolver extends UriResolver {
  final MemoryResourceProvider resourceProvider;

  AbsoluteUriResolver(this.resourceProvider);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    return new FileSource(
        resourceProvider.getFile(resourceProvider.pathContext.fromUri(uri)),
        actualUri);
  }
}

class CustomUriResolver extends UriResolver {
  String uriPath;
  CustomUriResolver({this.uriPath});

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) =>
      createSource(path: uriPath);
}

@reflectiveTest
class SourceFactoryTest with ResourceProviderMixin {
  void test_creation() {
    expect(new SourceFactory([]), isNotNull);
  }

  void test_fromEncoding_invalidUri() {
    SourceFactory factory = new SourceFactory([]);
    expect(() => factory.fromEncoding("<:&%>"), throwsArgumentError);
  }

  void test_fromEncoding_noResolver() {
    SourceFactory factory = new SourceFactory([]);
    expect(() => factory.fromEncoding("foo:/does/not/exist.dart"),
        throwsArgumentError);
  }

  void test_fromEncoding_valid() {
    String encoding = "file:///does/not/exist.dart";
    SourceFactory factory = new SourceFactory(
        [new UriResolver_SourceFactoryTest_test_fromEncoding_valid(encoding)]);
    expect(factory.fromEncoding(encoding), isNotNull);
  }

  void test_resolveUri_absolute() {
    UriResolver_absolute resolver = new UriResolver_absolute();
    SourceFactory factory = new SourceFactory([resolver]);
    factory.resolveUri(null, "dart:core");
    expect(resolver.invoked, isTrue);
  }

  void test_resolveUri_nonAbsolute_absolute() {
    SourceFactory factory =
        new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
    String sourcePath = convertPath('/does/not/exist.dart');
    String targetRawPath = '/does/not/matter.dart';
    String targetPath = convertPath(targetRawPath);
    String targetUri = toUri(targetRawPath).toString();
    Source sourceSource = new FileSource(getFile(sourcePath));
    Source result = factory.resolveUri(sourceSource, targetUri);
    expect(result.fullName, targetPath);
  }

  void test_resolveUri_nonAbsolute_relative() {
    SourceFactory factory =
        new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
    Source containingSource = new FileSource(getFile('/does/not/have.dart'));
    Source result = factory.resolveUri(containingSource, 'exist.dart');
    expect(result.fullName, convertPath('/does/not/exist.dart'));
  }

  void test_resolveUri_nonAbsolute_relative_package() {
    MemoryResourceProvider provider = new MemoryResourceProvider();
    pathos.Context context = provider.pathContext;
    String packagePath =
        context.joinAll([context.separator, 'path', 'to', 'package']);
    String libPath = context.joinAll([packagePath, 'lib']);
    String dirPath = context.joinAll([libPath, 'dir']);
    String firstPath = context.joinAll([dirPath, 'first.dart']);
    String secondPath = context.joinAll([dirPath, 'second.dart']);

    provider.newFolder(packagePath);
    Folder libFolder = provider.newFolder(libPath);
    provider.newFolder(dirPath);
    File firstFile = provider.newFile(firstPath, '');
    provider.newFile(secondPath, '');

    PackageMapUriResolver resolver = new PackageMapUriResolver(provider, {
      'package': [libFolder]
    });
    SourceFactory factory = new SourceFactory([resolver]);
    Source librarySource =
        firstFile.createSource(Uri.parse('package:package/dir/first.dart'));

    Source result = factory.resolveUri(librarySource, 'second.dart');
    expect(result, isNotNull);
    expect(result.fullName, secondPath);
    expect(result.uri.toString(), 'package:package/dir/second.dart');
  }

  void test_restoreUri() {
    File file1 = getFile("/some/file1.dart");
    File file2 = getFile("/some/file2.dart");
    Source source1 = new FileSource(file1);
    Source source2 = new FileSource(file2);
    Uri expected1 = Uri.parse("file:///my_file.dart");
    SourceFactory factory =
        new SourceFactory([new UriResolver_restoreUri(source1, expected1)]);
    expect(factory.restoreUri(source1), same(expected1));
    expect(factory.restoreUri(source2), same(null));
  }
}

class UriResolver_absolute extends UriResolver {
  bool invoked = false;

  UriResolver_absolute();

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    invoked = true;
    return null;
  }
}

class UriResolver_restoreUri extends UriResolver {
  Source source1;
  Uri expected1;
  UriResolver_restoreUri(this.source1, this.expected1);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) => null;

  @override
  Uri restoreAbsolute(Source source) {
    if (identical(source, source1)) {
      return expected1;
    }
    return null;
  }
}

class UriResolver_SourceFactoryTest_test_fromEncoding_valid
    extends UriResolver {
  String encoding;
  UriResolver_SourceFactoryTest_test_fromEncoding_valid(this.encoding);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    if (uri.toString() == encoding) {
      return new TestSource();
    }
    return null;
  }
}
