// Copyright (c) 2014, 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/generated/engine.dart' show TimestampedData;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart';

import 'file_system_test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(FileSystemExceptionTest);
    defineReflectiveTests(MemoryFileSourceExistingTest);
    defineReflectiveTests(MemoryFileSourceNotExistingTest);
    defineReflectiveTests(MemoryFileTest);
    defineReflectiveTests(MemoryFolderTest);
    defineReflectiveTests(MemoryResourceProviderTest);
  });
}

abstract class BaseTest extends FileSystemTestSupport {
  /// The resource provider to be used by the tests. Tests should use [provider]
  /// to access the resource provider.
  MemoryResourceProvider _provider;

  /// The absolute path to the temporary directory in which all of the tests are
  /// to work.
  @override
  /*late*/ String tempPath;

  /// A path to a folder within the [tempPath] that can be used by tests.
  @override
  /*late*/ String defaultFolderPath;

  /// A path to a file within the [defaultFolderPath] that can be used by tests.
  @override
  /*late*/ String defaultFilePath;

  /// The content used for the file at the [defaultFilePath] if it is created
  /// and no other content is provided.
  @override
  String get defaultFileContent => 'a';

  /// Return the resource provider to be used by the tests.
  @override
  MemoryResourceProvider get provider => _provider ??= createProvider();

  /// Create the resource provider to be used by the tests. Subclasses can
  /// override this method to change the class of resource provider that is
  /// used.
  MemoryResourceProvider createProvider() => MemoryResourceProvider();

  @override
  File getFile({@required bool exists, String content, String filePath}) {
    if (filePath == null) {
      filePath = defaultFilePath;
    } else {
      filePath = provider.convertPath(filePath);
    }
    if (exists) {
      provider.newFile(filePath, content ?? defaultFileContent);
    }
    return provider.getFile(filePath);
  }

  @override
  Folder getFolder({@required bool exists, String folderPath}) {
    if (folderPath == null) {
      folderPath = defaultFolderPath;
    } else {
      folderPath = provider.convertPath(folderPath);
    }
    if (exists) {
      provider.newFolder(folderPath);
    }
    return provider.getFolder(folderPath);
  }

  setUp() {
    tempPath = provider.convertPath('/temp');
    defaultFolderPath = join(tempPath, 'bar');
    defaultFilePath = join(tempPath, 'bar', 'test.dart');
  }
}

@reflectiveTest
class FileSystemExceptionTest {
  test_constructor() {
    var exception = FileSystemException('/my/path', 'my message');
    expect(exception.path, '/my/path');
    expect(exception.message, 'my message');
    expect(exception.toString(),
        'FileSystemException(path=/my/path; message=my message)');
  }
}

@reflectiveTest
class MemoryFileSourceExistingTest extends BaseTest {
  /*late*/ String sourcePath;
  /*late*/ Source source;

  @override
  setUp() {
    super.setUp();
    File file = getFile(exists: true);
    sourcePath = file.path;
    source = file.createSource();
  }

  test_contents() {
    TimestampedData<String> contents = source.contents;
    expect(contents.data, defaultFileContent);
  }

  test_equals_false_differentFile() {
    File fileA = getFile(exists: false, filePath: join(tempPath, 'a.dart'));
    File fileB = getFile(exists: false, filePath: join(tempPath, 'b.dart'));
    Source sourceA = fileA.createSource();
    Source sourceB = fileB.createSource();

    expect(sourceA == sourceB, isFalse);
  }

  test_equals_false_notMemorySource() {
    expect(source == Object(), isFalse);
  }

  test_equals_true_sameFile() {
    Source sourceA = getFile(exists: false).createSource();
    Source sourceB = getFile(exists: false).createSource();

    expect(sourceA == sourceB, isTrue);
  }

  test_equals_true_self() {
    expect(source == source, isTrue);
  }

  test_exists() {
    expect(source.exists(), isTrue);
  }

  test_fullName() {
    expect(source.fullName, sourcePath);
  }

  test_hashCode() {
    expect(source.hashCode, isNotNull);
  }

  test_resolveRelative() {
    Uri relative = resolveRelativeUri(
        source.uri,
        provider.pathContext
            .toUri(provider.pathContext.join('bar', 'baz.dart')));
    expect(
        relative,
        provider.pathContext
            .toUri(provider.convertPath('/temp/bar/bar/baz.dart')));
  }

  test_resolveRelative_dart() {
    File file = getFile(
        exists: false,
        filePath: provider.convertPath('/sdk/lib/core/core.dart'));
    Source source = file.createSource(Uri.parse('dart:core'));

    Uri resolved = resolveRelativeUri(source.uri, Uri.parse('int.dart'));
    expect(resolved.toString(), 'dart:core/int.dart');
  }

  test_shortName() {
    expect(source.shortName, 'test.dart');
  }
}

@reflectiveTest
class MemoryFileSourceNotExistingTest extends BaseTest {
  /*late*/ String sourcePath;
  /*late*/ Source source;

  @override
  setUp() {
    super.setUp();
    File file = getFile(exists: false);
    sourcePath = file.path;
    source = file.createSource();
  }

  test_contents() {
    expect(() => source.contents, throwsA(isFileSystemException));
  }

  test_exists() {
    expect(source.exists(), isFalse);
  }

  test_fullName() {
    expect(source.fullName, sourcePath);
  }

  test_modificationStamp() {
    expect(source.modificationStamp, -1);
  }

  test_resolveRelative() {
    Uri relative = resolveRelativeUri(
        source.uri,
        provider.pathContext
            .toUri(provider.pathContext.join('bar', 'baz.dart')));
    expect(
        relative,
        provider.pathContext
            .toUri(provider.convertPath('/temp/bar/bar/baz.dart')));
  }

  test_shortName() {
    expect(source.shortName, 'test.dart');
  }
}

@reflectiveTest
class MemoryFileTest extends BaseTest with FileTestMixin {
  @override
  test_delete_notExisting() {
    File file = getFile(exists: false);
    expect(file.exists, isFalse);

    expect(() => file.delete(), throwsA(const TypeMatcher<ArgumentError>()));
  }

  @override
  test_renameSync_notExisting() {
    String oldPath = join(tempPath, 'file.txt');
    String newPath = join(tempPath, 'new-file.txt');
    File oldFile = getFile(exists: true, filePath: oldPath);

    File newFile = oldFile.renameSync(newPath);
    expect(oldFile.path, oldPath);
    expect(oldFile.exists, isFalse);
    expect(newFile.path, newPath);
    expect(newFile.exists, isTrue);
    expect(newFile.readAsStringSync(), defaultFileContent);
  }

  @override
  test_resolveSymbolicLinksSync_links_existing() {
    var a = provider.convertPath('/test/lib/a.dart');
    var b = provider.convertPath('/test/lib/b.dart');

    provider.newLink(b, a);
    provider.newFile(a, 'aaa');

    var resolved = provider.getFile(b).resolveSymbolicLinksSync();
    expect(resolved.path, a);
  }

  @override
  test_resolveSymbolicLinksSync_links_notExisting() {
    var a = provider.convertPath('/test/lib/a.dart');
    var b = provider.convertPath('/test/lib/b.dart');

    provider.newLink(b, a);

    expect(() {
      provider.getFile(b).resolveSymbolicLinksSync();
    }, throwsA(isFileSystemException));
  }

  @override
  test_resolveSymbolicLinksSync_noLinks_notExisting() {
    File file = getFile(exists: false);

    expect(() {
      file.resolveSymbolicLinksSync();
    }, throwsA(isFileSystemException));
  }

  @override
  test_writeAsBytesSync_notExisting() {
    File file = getFile(exists: false);

    file.writeAsBytesSync(<int>[99, 99]);
    expect(file.exists, true);
    expect(file.readAsBytesSync(), <int>[99, 99]);
  }

  @override
  test_writeAsStringSync_notExisting() {
    File file = getFile(exists: false);

    file.writeAsStringSync('cc');
    expect(file.exists, true);
    expect(file.readAsStringSync(), 'cc');
  }
}

@reflectiveTest
class MemoryFolderTest extends BaseTest with FolderTestMixin {
  test_resolveSymbolicLinksSync() {
    var lib = provider.convertPath('/test/lib');
    var foo = provider.convertPath('/test/lib/foo');

    provider.newLink(foo, lib);
    provider.newFolder(lib);

    var resolved = provider.getFolder(foo).resolveSymbolicLinksSync();
    expect(resolved.path, lib);
  }
}

@reflectiveTest
class MemoryResourceProviderTest extends BaseTest
    with ResourceProviderTestMixin {
  test_deleteFile_existing() {
    File file = getFile(exists: true);
    expect(file.exists, isTrue);

    provider.deleteFile(defaultFilePath);
    expect(file.exists, isFalse);
  }

  test_deleteFile_folder() {
    Folder folder = getFolder(exists: true);

    expect(() => provider.deleteFile(defaultFolderPath), throwsArgumentError);
    expect(folder.exists, isTrue);
  }

  test_deleteFile_notExisting() {
    File file = getFile(exists: false);

    expect(() => provider.deleteFile(defaultFilePath), throwsArgumentError);
    expect(file.exists, isFalse);
  }

  test_modifyFile_existing_file() {
    File file = getFile(exists: true);

    provider.modifyFile(file.path, 'contents 2');
    expect(file.readAsStringSync(), 'contents 2');
  }

  test_modifyFile_existing_folder() {
    getFolder(exists: true);

    expect(() => provider.modifyFile(defaultFolderPath, 'contents'),
        throwsArgumentError);
    expect(provider.getResource(defaultFolderPath), isFolder);
  }

  test_modifyFile_notExisting() {
    getFile(exists: false);

    expect(() => provider.modifyFile(defaultFilePath, 'contents'),
        throwsArgumentError);
    Resource file = provider.getResource(defaultFilePath);
    expect(file, isFile);
    expect(file.exists, isFalse);
  }

  test_newFileWithBytes() {
    List<int> bytes = <int>[1, 2, 3, 4, 5];

    provider.newFileWithBytes(defaultFilePath, bytes);
    Resource file = provider.getResource(defaultFilePath);
    expect(file, isFile);
    expect(file.exists, isTrue);
    expect((file as File).readAsBytesSync(), bytes);
  }

  test_newFolder_emptyPath() {
    expect(() => provider.newFolder(''), throwsArgumentError);
  }

  test_newFolder_existing_file() {
    getFile(exists: true);

    expect(() => provider.newFolder(defaultFilePath), throwsArgumentError);
  }

  test_newFolder_existing_folder() {
    Folder folder = getFolder(exists: true);

    Folder newFolder = provider.newFolder(folder.path);
    expect(newFolder, folder);
  }

  test_newFolder_notAbsolute() {
    expect(() => provider.newFolder('not/absolute'), throwsArgumentError);
  }

  test_newLink_folder() {
    provider.newLink(
      provider.convertPath('/test/lib/foo'),
      provider.convertPath('/test/lib'),
    );

    provider.newFile(
      provider.convertPath('/test/lib/a.dart'),
      'aaa',
    );

    {
      var path = '/test/lib/foo/a.dart';
      var convertedPath = provider.convertPath(path);
      var file = provider.getFile(convertedPath);
      expect(file.exists, true);
      expect(file.modificationStamp, isNonNegative);
      expect(file.readAsStringSync(), 'aaa');
    }

    {
      var path = '/test/lib/foo/foo/a.dart';
      var convertedPath = provider.convertPath(path);
      var file = provider.getFile(convertedPath);
      expect(file.exists, true);
      expect(file.modificationStamp, isNonNegative);
      expect(file.readAsStringSync(), 'aaa');
    }
  }

  @override
  test_pathContext() {
    if (path.style == path.Style.windows) {
      // On Windows the path context is replaced by one whose current directory
      // is the root of the 'C' drive.
      path.Context context = provider.pathContext;
      expect(context.style, path.Style.windows);
      expect(context.current, 'C:\\');
    } else {
      super.test_pathContext();
    }
  }

  test_watch_createFile() {
    String rootPath = provider.convertPath('/my/path');
    provider.newFolder(rootPath);
    return _watchingFolder(rootPath, (changesReceived) {
      expect(changesReceived, hasLength(0));
      String path = provider.pathContext.join(rootPath, 'foo');

      provider.newFile(path, 'contents');
      return _delayed(() {
        expect(changesReceived, hasLength(1));
        expect(changesReceived[0].type, equals(ChangeType.ADD));
        expect(changesReceived[0].path, equals(path));
      });
    });
  }

  test_watch_deleteFile() {
    String rootPath = provider.convertPath('/my/path');
    provider.newFolder(rootPath);
    String path = provider.pathContext.join(rootPath, 'foo');
    provider.newFile(path, 'contents 1');
    return _watchingFolder(rootPath, (changesReceived) {
      expect(changesReceived, hasLength(0));

      provider.deleteFile(path);
      return _delayed(() {
        expect(changesReceived, hasLength(1));
        expect(changesReceived[0].type, equals(ChangeType.REMOVE));
        expect(changesReceived[0].path, equals(path));
      });
    });
  }

  test_watch_modifyFile() {
    String rootPath = provider.convertPath('/my/path');
    provider.newFolder(rootPath);
    String path = provider.pathContext.join(rootPath, 'foo');
    provider.newFile(path, 'contents 1');
    return _watchingFolder(rootPath, (changesReceived) {
      expect(changesReceived, hasLength(0));

      provider.modifyFile(path, 'contents 2');
      return _delayed(() {
        expect(changesReceived, hasLength(1));
        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
        expect(changesReceived[0].path, equals(path));
      });
    });
  }

  test_watch_modifyFile_inSubDir() {
    String rootPath = provider.convertPath('/my/path');
    provider.newFolder(rootPath);
    String subdirPath = provider.pathContext.join(rootPath, 'foo');
    provider.newFolder(subdirPath);
    String path = provider.pathContext.join(rootPath, 'bar');
    provider.newFile(path, 'contents 1');
    return _watchingFolder(rootPath, (changesReceived) {
      expect(changesReceived, hasLength(0));

      provider.modifyFile(path, 'contents 2');
      return _delayed(() {
        expect(changesReceived, hasLength(1));
        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
        expect(changesReceived[0].path, equals(path));
      });
    });
  }

  Future _delayed(Function() computation) {
    return Future.delayed(Duration.zero, computation);
  }

  _watchingFolder(
      String path, Function(List<WatchEvent> changesReceived) test) {
    var folder = provider.getResource(path) as Folder;
    var changesReceived = <WatchEvent>[];
    folder.changes.listen(changesReceived.add);
    return test(changesReceived);
  }
}
