// 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:async';
import 'dart:io';

import '../event.dart';
import '../event_batching.dart';
import '../file_watcher.dart';
import '../resubscribable.dart';
import '../watch_event.dart';

/// Uses the native file system notifications to watch for filesystem events.
///
/// Single-file notifications are much simpler than those for multiple files, so
/// this doesn't need to be split out into multiple OS-specific classes.
class NativeFileWatcher extends ResubscribableWatcher implements FileWatcher {
  NativeFileWatcher(String path) : super(path, _NativeFileWatcher.new);
}

class _NativeFileWatcher implements FileWatcher, ManuallyClosedWatcher {
  @override
  final String path;

  @override
  Stream<WatchEvent> get events => _eventsController.stream;
  final _eventsController = StreamController<WatchEvent>.broadcast();

  @override
  bool get isReady => _readyCompleter.isCompleted;

  @override
  Future<void> get ready => _readyCompleter.future;
  final _readyCompleter = Completer<void>();

  StreamSubscription<List<Event>>? _subscription;

  /// On MacOS only, whether the file existed on startup.
  bool? _existedAtStartup;

  _NativeFileWatcher(this.path) {
    _listen();

    // We don't need to do any initial set-up, so we're ready immediately after
    // being listened to.
    _readyCompleter.complete();
  }

  void _listen() async {
    var file = File(path);

    // Batch the events together so that we can dedupe them.
    var stream = file.watch().batchNearbyMicrotasksAndConvertEvents();

    if (Platform.isMacOS) {
      var existedAtStartupFuture = file.exists();
      // Delay processing watch events until the existence check finishes.
      stream = stream.asyncMap((event) async {
        _existedAtStartup ??= await existedAtStartupFuture;
        return event;
      });
    }

    _subscription = stream.listen(
      _onBatch,
      onError: _eventsController.addError,
      onDone: _onDone,
    );
  }

  void _onBatch(List<Event> batch) {
    if (batch.any((event) => event.type == EventType.delete)) {
      // If the file is deleted, the underlying stream will close. We handle
      // emitting our own REMOVE event in [_onDone].
      return;
    }

    if (Platform.isMacOS) {
      // On MacOS, a spurious `create` event can be received for a file that is
      // created just before the `watch`. If the file existed at startup then it
      // should be ignored.
      if (_existedAtStartup! &&
          batch.every((event) => event.type == EventType.createFile)) {
        return;
      }
    }

    _eventsController.add(WatchEvent(ChangeType.MODIFY, path));
  }

  void _onDone() async {
    var fileExists = await File(path).exists();

    // Check for this after checking whether the file exists because it's
    // possible that [close] was called between [File.exists] being called and
    // it completing.
    if (_eventsController.isClosed) return;

    if (fileExists) {
      // If the file exists now, it was probably removed and quickly replaced;
      // this can happen for example when another file is moved on top of it.
      // Re-subscribe and report a modify event.
      _eventsController.add(WatchEvent(ChangeType.MODIFY, path));
      _listen();
    } else {
      _eventsController.add(WatchEvent(ChangeType.REMOVE, path));
      close();
    }
  }

  @override
  void close() {
    _subscription?.cancel();
    _subscription = null;
    _eventsController.close();
  }
}
