// 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 '../file_watcher.dart';
import '../polling.dart';
import '../resubscribable.dart';
import '../watch_event.dart';

/// Periodically polls a file for changes.
class PollingFileWatcher extends ResubscribableWatcher implements FileWatcher {
  PollingFileWatcher(String path, {Duration? pollingDelay})
      : super(path, () {
          return _PollingFileWatcher(
              path, pollingDelay ?? const Duration(seconds: 1));
        });
}

class _PollingFileWatcher 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>();

  /// The timer that controls polling.
  late final Timer _timer;

  PollResult _previousPollResult = PollResult.notAFile();

  _PollingFileWatcher(this.path, Duration pollingDelay) {
    _timer = Timer.periodic(pollingDelay, (_) => _poll());
    _poll();
  }

  /// Checks the mtime of the file and whether it's been removed.
  Future<void> _poll() async {
    // We don't mark the file as removed if this is the first poll. Instead,
    // below we forward the dart:io error that comes from trying to read the
    // mtime below.
    var pathExists = await File(path).exists();
    if (_eventsController.isClosed) return;

    if (_previousPollResult.fileExists && !pathExists) {
      _flagReady();
      _eventsController.add(WatchEvent(ChangeType.REMOVE, path));
      unawaited(close());
      return;
    }

    PollResult pollResult;
    try {
      pollResult = await PollResult.poll(path);
    } on FileSystemException catch (error, stackTrace) {
      if (!_eventsController.isClosed) {
        _flagReady();
        _eventsController.addError(error, stackTrace);
        await close();
      }
      return;
    }
    if (_eventsController.isClosed) {
      _flagReady();
      return;
    }

    if (!isReady) {
      // If this is the first poll, don't emit an event, just set the poll
      // result and complete the completer.
      _previousPollResult = pollResult;
      _flagReady();
      return;
    }

    if (_previousPollResult == pollResult) return;

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

  /// Flags this watcher as ready if it has not already been done.
  void _flagReady() {
    if (!isReady) {
      _readyCompleter.complete();
    }
  }

  @override
  Future<void> close() async {
    _timer.cancel();
    await _eventsController.close();
  }
}
