// Copyright (c) 2021, 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:async';
import 'dart:isolate';

import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/bazel.dart';
import 'package:analyzer/src/workspace/bazel_watcher.dart';
import 'package:async/async.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(BazelWatcherTest);
  });
}

@reflectiveTest
class BazelWatcherTest with ResourceProviderMixin {
  late final BazelWorkspace workspace;

  void test_bazelFileWatcher() async {
    _addResources([
      '/workspace/WORKSPACE',
    ]);
    var candidates = [
      convertPath('/workspace/bazel-bin/my/module/test1.dart'),
      convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
    ];
    var watcher = BazelFilePoller(resourceProvider, candidates);

    // First do some tests with the first candidate path.
    _addResources([candidates[0]]);

    var event = watcher.poll()!;

    expect(event.type, ChangeType.ADD);
    expect(event.path, candidates[0]);

    modifyFile(candidates[0], 'const foo = 42;');

    event = watcher.poll()!;

    expect(event.type, ChangeType.MODIFY);
    expect(event.path, candidates[0]);

    _deleteResources([candidates[0]]);

    event = watcher.poll()!;

    expect(event.type, ChangeType.REMOVE);
    expect(event.path, candidates[0]);

    // Now check that if we add the *second* candidate, we'll get the
    // notification for it.
    _addResources([candidates[1]]);

    event = watcher.poll()!;

    expect(event.type, ChangeType.ADD);
    expect(event.path, candidates[1]);

    // Next poll should be `null` since there were no changes.
    expect(watcher.poll(), isNull);
  }

  void test_bazelFileWatcherIsolate() async {
    _addResources([
      '/workspace/WORKSPACE',
    ]);
    var candidates1 = [
      convertPath('/workspace/bazel-bin/my/module/test1.dart'),
      convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
    ];
    var candidates2 = [
      convertPath('/workspace/bazel-bin/my/module/test2.dart'),
      convertPath('/workspace/bazel-genfiles/my/module/test2.dart'),
    ];
    var trigger = _MockPollTrigger();
    var recPort = ReceivePort();
    // Note that we provide below a dummy `ReceivePort` that will *not* be used.
    // We'll directly call `handleRequest` to avoid any problems with various
    // interleavings of async functions.
    var dummyRecPort = ReceivePort();
    var watcher = BazelFileWatcherIsolate(
        dummyRecPort, recPort.sendPort, resourceProvider,
        pollTriggerFactory: (_) => trigger)
      ..start();
    var queue = StreamQueue(recPort);

    await queue.next as BazelWatcherIsolateStarted;

    watcher.handleRequest(BazelWatcherStartWatching(
        convertPath('/workspace'),
        BazelSearchInfo(
            convertPath('/workspace/my/module/test1.dart'), candidates1)));
    watcher.handleRequest(BazelWatcherStartWatching(
        convertPath('/workspace'),
        BazelSearchInfo(
            convertPath('/workspace/my/module/test2.dart'), candidates2)));

    // First do some tests with the first candidate path.
    _addResources([candidates1[0]]);

    trigger.controller.add('');
    var events = (await queue.next as BazelWatcherEvents).events;

    expect(events, hasLength(1));
    expect(events[0].path, candidates1[0]);
    expect(events[0].type, ChangeType.ADD);

    // Now let's take a look at the second file.
    _addResources([candidates2[1]]);

    trigger.controller.add('');
    events = (await queue.next as BazelWatcherEvents).events;

    expect(events, hasLength(1));
    expect(events[0].path, candidates2[1]);
    expect(events[0].type, ChangeType.ADD);

    expect(watcher.numWatchedFiles(), 2);

    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
        convertPath('/workspace/my/module/test1.dart')));

    expect(watcher.numWatchedFiles(), 1);

    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
        convertPath('/workspace/my/module/test2.dart')));

    expect(watcher.numWatchedFiles(), 0);

    watcher.handleRequest(BazelWatcherShutdownIsolate());
    await watcher.hasFinished;

    // We need to do this manually, since it's the callers responsibility to
    // close this port (the one owned by `watcher` should've been closed when
    // handling the "shutdown" request).
    recPort.close();
  }

  void test_bazelFileWatcherIsolate_multipleWorkspaces() async {
    _addResources([
      '/workspace1/WORKSPACE',
      '/workspace2/WORKSPACE',
    ]);
    var candidates1 = [
      convertPath('/workspace1/bazel-bin/my/module/test1.dart'),
      convertPath('/workspace1/bazel-genfiles/my/module/test1.dart'),
    ];
    var candidates2 = [
      convertPath('/workspace2/bazel-bin/my/module/test2.dart'),
      convertPath('/workspace2/bazel-genfiles/my/module/test2.dart'),
    ];
    _MockPollTrigger? trigger1;
    _MockPollTrigger? trigger2;
    var triggerFactory = (String workspace) {
      if (workspace == convertPath('/workspace1')) {
        trigger1 = _MockPollTrigger();
        return trigger1!;
      } else if (workspace == convertPath('/workspace2')) {
        trigger2 = _MockPollTrigger();
        return trigger2!;
      } else {
        throw ArgumentError('Got unexpected workspace: `$workspace`');
      }
    };
    var recPort = ReceivePort();
    // Note that we provide below a dummy `ReceivePort` that will *not* be used.
    // We'll directly call `handleRequest` to avoid any problems with various
    // interleavings of async functions.
    var dummyRecPort = ReceivePort();
    var watcher = BazelFileWatcherIsolate(
        dummyRecPort, recPort.sendPort, resourceProvider,
        pollTriggerFactory: triggerFactory)
      ..start();
    var queue = StreamQueue(recPort);

    await queue.next as BazelWatcherIsolateStarted;

    watcher.handleRequest(BazelWatcherStartWatching(
        convertPath('/workspace1'),
        BazelSearchInfo(
            convertPath('/workspace1/my/module/test1.dart'), candidates1)));
    watcher.handleRequest(BazelWatcherStartWatching(
        convertPath('/workspace2'),
        BazelSearchInfo(
            convertPath('/workspace2/my/module/test2.dart'), candidates2)));

    // First do some tests with the first candidate path.
    _addResources([candidates1[0]]);

    trigger1!.controller.add('');
    var events = (await queue.next as BazelWatcherEvents).events;

    expect(events, hasLength(1));
    expect(events[0].path, candidates1[0]);
    expect(events[0].type, ChangeType.ADD);

    // Now let's take a look at the second file.
    _addResources([candidates2[1]]);

    trigger2!.controller.add('');
    events = (await queue.next as BazelWatcherEvents).events;

    expect(events, hasLength(1));
    expect(events[0].path, candidates2[1]);
    expect(events[0].type, ChangeType.ADD);

    expect(watcher.numWatchedFiles(), 2);

    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace1'),
        convertPath('/workspace1/my/module/test1.dart')));

    expect(watcher.numWatchedFiles(), 1);

    watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace2'),
        convertPath('/workspace2/my/module/test2.dart')));

    expect(watcher.numWatchedFiles(), 0);

    watcher.handleRequest(BazelWatcherShutdownIsolate());
    await watcher.hasFinished;

    // We need to do this manually, since it's the callers responsibility to
    // close this port (the one owned by `watcher` should've been closed when
    // handling the "shutdown" request).
    recPort.close();
  }

  void test_bazelFileWatcherWithFolder() async {
    _addResources([
      '/workspace/WORKSPACE',
    ]);

    // The `_addResources`/`_deleteResources` functions recognize a folder by a
    // trailing `/`, but everywhere else we need to use normalized paths.
    var addFolder = (path) => _addResources(['$path/']);
    var deleteFolder = (path) => _deleteResources(['$path/']);

    var candidates = [
      convertPath('/workspace/bazel-out'),
      convertPath('/workspace/blaze-out'),
    ];
    var watcher = BazelFilePoller(resourceProvider, candidates);

    // First do some tests with the first candidate path.
    addFolder(candidates[0]);
    var event = watcher.poll()!;

    expect(event.type, ChangeType.ADD);
    expect(event.path, candidates[0]);

    deleteFolder(candidates[0]);
    event = watcher.poll()!;

    expect(event.type, ChangeType.REMOVE);
    expect(event.path, candidates[0]);

    // Now check that if we add the *second* candidate, we'll get the
    // notification for it.
    addFolder(candidates[1]);
    event = watcher.poll()!;

    expect(event.type, ChangeType.ADD);
    expect(event.path, candidates[1]);

    // Next poll should be `null` since there were no changes.
    expect(watcher.poll(), isNull);
  }

  /// Create new files and directories from [paths].
  void _addResources(List<String> paths) {
    for (String path in paths) {
      if (path.endsWith('/')) {
        newFolder(path.substring(0, path.length - 1));
      } else {
        newFile2(path, '');
      }
    }
  }

  /// Create new files and directories from [paths].
  void _deleteResources(List<String> paths) {
    for (String path in paths) {
      if (path.endsWith('/')) {
        deleteFolder(path.substring(0, path.length - 1));
      } else {
        deleteFile(path);
      }
    }
  }
}

class _MockPollTrigger implements PollTrigger {
  final controller = StreamController<Object>();

  @override
  Stream<Object> get stream => controller.stream;

  @override
  void cancel() {
    return;
  }
}
