// 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 = const AnalysisStatus._(false);
  static const ANALYZING = const 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 = new Completer<void>();

  /**
   * Return a [Future] that completes when [notify] is called at least once.
   */
  Future<void> get signal async {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    await _completer.future;
    _completer = new 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 = new 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 ??= new 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 ?? new Future<void>.value();
  }
}
