// Copyright (c) 2016, 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';

/**
 * The status of analysis.
 */
class AnalysisStatus {
  static const IDLE = AnalysisStatus._(false);
  static const ANALYZING = AnalysisStatus._(true);

  final bool _analyzing;

  const AnalysisStatus._(this._analyzing);

  /**
   * Return `true` if the scheduler is analyzing.
   */
  bool get isAnalyzing => _analyzing;

  /**
   * Return `true` if the scheduler is idle.
   */
  bool get isIdle => !_analyzing;

  @override
  String toString() => _analyzing ? 'analyzing' : 'idle';
}

/**
 * [Monitor] can be used to wait for a signal.
 *
 * Signals are not queued, the client will receive exactly one signal
 * regardless of the number of [notify] invocations. The [signal] is reset
 * after completion and will not complete until [notify] is called next time.
 */
class Monitor {
  Completer<void> _completer = Completer<void>();

  /**
   * Return a [Future] that completes when [notify] is called at least once.
   */
  Future<void> get signal async {
    await _completer.future;
    _completer = Completer<void>();
  }

  /**
   * Complete the [signal] future if it is not completed yet. It is safe to
   * call this method multiple times, but the [signal] will complete only once.
   */
  void notify() {
    if (!_completer.isCompleted) {
      _completer.complete(null);
    }
  }
}

/**
 * Helper for managing transitioning [AnalysisStatus].
 */
class StatusSupport {
  /**
   * The controller for the [stream].
   */
  final _statusController = StreamController<AnalysisStatus>();

  /**
   * The last status sent to the [stream].
   */
  AnalysisStatus _currentStatus = AnalysisStatus.IDLE;

  /**
   * If non-null, a completer which should be completed on the next transition
   * to idle.
   */
  Completer<void> _idleCompleter;

  /**
   * Return the last status sent to the [stream].
   */
  AnalysisStatus get currentStatus => _currentStatus;

  /**
   * Return the stream that produces [AnalysisStatus] events.
   */
  Stream<AnalysisStatus> get stream => _statusController.stream;

  /**
   * Prepare for the scheduler to start analyzing, but do not notify the
   * [stream] yet.
   *
   * A call to [preTransitionToAnalyzing] has the same effect on [waitForIdle]
   * as a call to [transitionToAnalyzing], but it has no effect on the [stream].
   */
  void preTransitionToAnalyzing() {
    _idleCompleter ??= Completer<void>();
  }

  /**
   * Send a notification to the [stream] that the scheduler started analyzing.
   */
  void transitionToAnalyzing() {
    if (_currentStatus != AnalysisStatus.ANALYZING) {
      preTransitionToAnalyzing();
      _currentStatus = AnalysisStatus.ANALYZING;
      _statusController.add(AnalysisStatus.ANALYZING);
    }
  }

  /**
   * Send a notification to the [stream] stream that the scheduler is idle.
   */
  void transitionToIdle() {
    if (_currentStatus != AnalysisStatus.IDLE) {
      _currentStatus = AnalysisStatus.IDLE;
      _statusController.add(AnalysisStatus.IDLE);
    }
    _idleCompleter?.complete();
    _idleCompleter = null;
  }

  /**
   * Return a future that will be completed the next time the status is idle.
   *
   * If the status is currently idle, the returned future will be signaled
   * immediately.
   */
  Future<void> waitForIdle() {
    return _idleCompleter?.future ?? Future<void>.value();
  }
}
