// Copyright (c) 2018, 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 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/generated/package_build.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:mockito/mockito.dart';
import 'package:package_config/packages.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(PackageBuildFileUriResolverTest);
    defineReflectiveTests(PackageBuildPackageUriResolverTest);
    defineReflectiveTests(PackageBuildWorkspaceTest);
  });
}

class MockContextBuilder extends Mock implements ContextBuilder {}

class MockPackages extends Mock implements Packages {}

class MockUriResolver extends Mock implements UriResolver {}

@reflectiveTest
class PackageBuildFileUriResolverTest extends _BaseTest {
  PackageBuildWorkspace workspace;
  PackageBuildFileUriResolver resolver;

  void setUp() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    final ContextBuilder contextBuilder = new MockContextBuilder();
    final Packages packages = new MockPackages();
    when(contextBuilder.createPackageMap(_p('/workspace')))
        .thenReturn(packages);
    when(contextBuilder.convertPackagesToMap(packages))
        .thenReturn({'project': []});
    workspace =
        PackageBuildWorkspace.find(provider, _p('/workspace'), contextBuilder);
    resolver = new PackageBuildFileUriResolver(workspace);
    provider.newFile(_p('/workspace/test.dart'), '');
    provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/gen.dart'), '');
  }

  void test_resolveAbsolute_doesNotExist() {
    Source source = _resolvePath('/workspace/foo.dart');
    expect(source, isNotNull);
    expect(source.exists(), isFalse);
    expect(source.fullName, _p('/workspace/foo.dart'));
  }

  void test_resolveAbsolute_file() {
    Source source = _resolvePath('/workspace/test.dart');
    expect(source, isNotNull);
    expect(source.exists(), isTrue);
    expect(source.fullName, _p('/workspace/test.dart'));
  }

  void test_resolveAbsolute_folder() {
    Source source = _resolvePath('/workspace');
    expect(source, isNotNull);
    expect(source.exists(), isFalse);
    expect(source.fullName, _p('/workspace'));
  }

  void test_resolveAbsolute_generated_file_exists_one() {
    Source source = _resolvePath('/workspace/gen.dart');
    expect(source, isNotNull);
    expect(source.exists(), isTrue);
    expect(source.fullName,
        _p('/workspace/.dart_tool/build/generated/project/gen.dart'));
  }

  void test_resolveAbsolute_notFile_dartUri() {
    Uri uri = new Uri(scheme: 'dart', path: 'core');
    Source source = resolver.resolveAbsolute(uri);
    expect(source, isNull);
  }

  void test_resolveAbsolute_notFile_httpsUri() {
    Uri uri = new Uri(scheme: 'https', path: '127.0.0.1/test.dart');
    Source source = resolver.resolveAbsolute(uri);
    expect(source, isNull);
  }

  void test_restoreAbsolute() {
    Uri uri = provider.pathContext.toUri(_p('/workspace/test.dart'));
    Source source = resolver.resolveAbsolute(uri);
    expect(source, isNotNull);
    expect(resolver.restoreAbsolute(source), uri);
    expect(
        resolver.restoreAbsolute(
            new NonExistingSource(source.fullName, null, null)),
        uri);
  }

  Source _resolvePath(String absolutePosixPath) {
    String absolutePath = provider.convertPath(absolutePosixPath);
    Uri uri = provider.pathContext.toUri(absolutePath);
    return resolver.resolveAbsolute(uri);
  }
}

@reflectiveTest
class PackageBuildPackageUriResolverTest extends _BaseTest {
  PackageBuildWorkspace workspace;
  PackageBuildPackageUriResolver resolver;
  UriResolver packageUriResolver;

  Uri addPackageSource(String path, String uriStr, {bool create: true}) {
    Uri uri = Uri.parse(uriStr);
    final File file = create
        ? provider.newFile(_p(path), '')
        : provider.getResource(_p(path));
    final Source source = file.createSource(uri);
    when(packageUriResolver.resolveAbsolute(uri)).thenReturn(source);
    return uri;
  }

  void setUp() {
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
  }

  void test_resolveAbsolute_generated() {
    _addResources([
      '/workspace/.dart_tool/build/generated/project/lib/generated_file.dart',
    ]);
    final Uri sourceUri = addPackageSource('/workspace/lib/generated_file.dart',
        'package:project/generated_file.dart',
        create: false);
    _assertResolveUri(sourceUri,
        '/workspace/.dart_tool/build/generated/project/lib/generated_file.dart',
        exists: true);
  }

  void test_resolveAbsolute_null_notPackage() {
    _addResources([
      '/workspace/.dart_tool/build/generated',
    ]);
    Source source = resolver.resolveAbsolute(Uri.parse('dart:async'));
    expect(source, isNull);
  }

  void test_resolveAbsolute_null_startsWithSlash() {
    _addResources([
      '/workspace/.dart_tool/build/generated',
    ]);
    Source source =
        resolver.resolveAbsolute(Uri.parse('package:/foo/bar.dart'));
    expect(source, isNull);
  }

  void test_resolveAbsolute_source() {
    _addResources([
      '/workspace/.dart_tool/build/generated/project/lib/source_file.dart',
    ]);
    final Uri sourceUri = addPackageSource(
        '/workspace/lib/source_file.dart', 'package:project/source_file.dart');
    _assertResolveUri(sourceUri, '/workspace/lib/source_file.dart',
        exists: true);
  }

  void test_resolveAbsolute_workspace_doesNotExist() {
    _addResources([
      '/workspace/.dart_tool/build/generated',
    ]);
    final Uri sourceUri = addPackageSource(
        '/workspace/lib/doesNotExist.dart', 'package:project/doesNotExist.dart',
        create: false);
    _assertResolveUri(sourceUri, '/workspace/lib/doesNotExist.dart',
        exists: false);
  }

  void _addResources(List<String> paths, {String workspacePath: '/workspace'}) {
    for (String path in paths) {
      if (path.endsWith('/')) {
        provider.newFolder(_p(path.substring(0, path.length - 1)));
      } else {
        provider.newFile(_p(path), '');
      }
    }
    final contextBuilder = new MockContextBuilder();
    final packages = new MockPackages();
    when(contextBuilder.createPackageMap(_p(workspacePath)))
        .thenReturn(packages);
    when(contextBuilder.convertPackagesToMap(packages))
        .thenReturn({'project': []});
    workspace =
        PackageBuildWorkspace.find(provider, _p(workspacePath), contextBuilder);
    packageUriResolver = new MockUriResolver();
    resolver =
        new PackageBuildPackageUriResolver(workspace, packageUriResolver);
  }

  Source _assertResolveUri(Uri uri, String posixPath,
      {bool exists: true, bool restore: true}) {
    Source source = resolver.resolveAbsolute(uri);
    expect(source, isNotNull);
    expect(source.fullName, _p(posixPath));
    expect(source.uri, uri);
    expect(source.exists(), exists);
    // If enabled, test also "restoreAbsolute".
    if (restore) {
      Uri restoredUri = resolver.restoreAbsolute(source);
      expect(restoredUri.toString(), uri.toString());
    }
    return source;
  }
}

@reflectiveTest
class PackageBuildWorkspaceTest extends _BaseTest {
  void test_builtFile_currentProject() {
    provider.newFolder(_p('/workspace/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final libFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/lib/file.dart'), '');
    expect(workspace.builtFile(_p('lib/file.dart'), 'project'), libFile);
  }

  void test_builtFile_importedPackage() {
    provider.newFolder(_p('/workspace/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project', 'foo']);

    final libFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/foo/lib/file.dart'), '');
    expect(workspace.builtFile(_p('lib/file.dart'), 'foo'), libFile);
  }

  void test_builtFile_notInPackagesGetsHidden() {
    provider.newFolder(_p('/workspace/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);

    // Ensure package:bar is not configured.
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project', 'foo']);

    // Create a generated file in package:bar.
    provider.newFile(
        _p('/workspace/.dart_tool/build/generated/bar/lib/file.dart'), '');

    // Bar not in packages, file should not be returned.
    expect(workspace.builtFile('lib/file.dart', 'bar'), isNull);
  }

  void test_find_fail_notAbsolute() {
    expect(
        () => PackageBuildWorkspace.find(
            provider, _p('not_absolute'), new MockContextBuilder()),
        throwsArgumentError);
  }

  void test_find_hasDartToolAndPubspec() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace.root, _p('/workspace'));
    expect(workspace.projectPackageName, 'project');
  }

  void test_find_hasDartToolAndPubspec_inParentDirectory() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFolder(_p('/workspace/opened/up/a/child/dir/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/opened/up/a/child/dir/pubspec.yaml'),
        'name: subproject'.codeUnits);
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(provider,
        _p('/workspace/opened/up/a/child/dir'), new MockContextBuilder());
    expect(workspace.root, _p('/workspace/opened/up/a/child/dir'));
    expect(workspace.projectPackageName, 'subproject');
  }

  void
      test_find_hasDartToolAndPubspec_inParentDirectory_ignoresMalformedPubspec() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFolder(_p('/workspace/opened/up/a/child/dir/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/opened/up/a/child/dir/pubspec.yaml'),
        'not: yaml: here!!! 111'.codeUnits);
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(provider,
        _p('/workspace/opened/up/a/child/dir'), new MockContextBuilder());
    expect(workspace.root, _p('/workspace'));
    expect(workspace.projectPackageName, 'project');
  }

  void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloDartTool() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFolder(_p('/workspace/opened/up/a/child/dir'));
    provider.newFolder(_p('/workspace/opened/up/a/child/dir/.dart_tool/build'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(provider,
        _p('/workspace/opened/up/a/child/dir'), new MockContextBuilder());
    expect(workspace.root, _p('/workspace'));
    expect(workspace.projectPackageName, 'project');
  }

  void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloPubspec() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFolder(_p('/workspace/opened/up/a/child/dir'));
    provider.newFileWithBytes(
        _p('/workspace/opened/up/a/child/dir/pubspec.yaml'),
        'name: subproject'.codeUnits);
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(provider,
        _p('/workspace/opened/up/a/child/dir'), new MockContextBuilder());
    expect(workspace.root, _p('/workspace'));
    expect(workspace.projectPackageName, 'project');
  }

  void test_find_hasDartToolNoBuild() {
    // Edge case: an empty .dart_tool directory. Don't assume package:build.
    provider.newFolder(_p('/workspace/.dart_tool'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace, isNull);
  }

  void test_find_hasDartToolNoPubspec() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace, isNull);
  }

  void test_find_hasDartToolPubButNotBuild() {
    // Dart projects will have this directory, that don't use package:build.
    provider.newFolder(_p('/workspace/.dart_tool/pub'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace, isNull);
  }

  void test_find_hasMalformedPubspec() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'not: yaml: here! 1111'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace, isNull);
  }

  void test_find_hasPubspecNoDartTool() {
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
        provider, _p('/workspace'), new MockContextBuilder());
    expect(workspace, isNull);
  }

  void test_findFile_bin() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/bin'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final binFile = provider.newFile(_p('/workspace/bin/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/bin/file.dart')), binFile);
  }

  void test_findFile_binGenerated() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/bin'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final binFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/bin/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/bin/file.dart')), binFile);
  }

  void test_findFile_libGenerated() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/lib'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final libFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/lib/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/lib/file.dart')), libFile);
  }

  void test_findFile_test() {
    provider
        .newFolder(_p('/workspace/.dart_tool/build/generated/project/test'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final testFile = provider.newFile(_p('/workspace/test/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/test/file.dart')), testFile);
  }

  void test_findFile_testGenerated() {
    provider
        .newFolder(_p('/workspace/.dart_tool/build/generated/project/test'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final testFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/test/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/test/file.dart')), testFile);
  }

  void test_findFile_web() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/web'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final webFile = provider.newFile(_p('/workspace/web/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/web/file.dart')), webFile);
  }

  void test_findFile_webGenerated() {
    provider.newFolder(_p('/workspace/.dart_tool/build/generated/project/web'));
    provider.newFileWithBytes(
        _p('/workspace/pubspec.yaml'), 'name: project'.codeUnits);
    PackageBuildWorkspace workspace =
        _createWorkspace('/workspace', ['project']);

    final webFile = provider.newFile(
        _p('/workspace/.dart_tool/build/generated/project/web/file.dart'), '');
    expect(workspace.findFile(_p('/workspace/web/file.dart')), webFile);
  }

  PackageBuildWorkspace _createWorkspace(
      String root, List<String> packageNames) {
    final contextBuilder = new MockContextBuilder();
    final packages = new MockPackages();
    final packageMap = new Map.fromIterable(packageNames, value: ((_) => []));
    when(contextBuilder.createPackageMap(_p(root))).thenReturn(packages);
    when(contextBuilder.convertPackagesToMap(packages)).thenReturn(packageMap);
    when(packages.asMap()).thenReturn(packageMap);
    return PackageBuildWorkspace.find(provider, _p(root), contextBuilder);
  }
}

class _BaseTest {
  final MemoryResourceProvider provider = new MemoryResourceProvider();

  /**
   * Return the [provider] specific path for the given Posix [path].
   */
  String _p(String path) => provider.convertPath(path);
}
