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

import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';

/// Reports progress of long-running operations to the LSP client.
abstract class ProgressReporter {
  /// A no-op reporter that does nothing.
  static final noop = _NoopProgressReporter();

  /// Creates a reporter for a token that was supplied by the client and does
  /// not need creating prior to use.
  factory clientProvided(LspAnalysisServer server, ProgressToken token) =>
      _TokenProgressReporter(server, token);

  /// Creates a reporter for a new token that must be created prior to being
  /// used.
  ///
  /// If [token] is not supplied, a random identifier will be used.
  factory serverCreated(LspAnalysisServer server, [ProgressToken? token]) =>
      _ServerCreatedProgressReporter(server, token);

  new _();

  // TODO(dantup): Add support for cancellable progress notifications.
  FutureOr<void> begin(String title, {String? message});

  FutureOr<void> end([String message]);
}

class _NoopProgressReporter extends ProgressReporter {
  new() : super._();
  @override
  void begin(String title, {String? message}) {}
  @override
  void end([String? message]) {}
}

class _ServerCreatedProgressReporter extends _TokenProgressReporter {
  static final _random = Random();
  Future<bool>? _tokenBeginRequest;

  new(LspAnalysisServer server, ProgressToken? token)
    : super(server, token ?? ProgressToken.t2(_randomTokenIdentifier()));

  @override
  Future<void> begin(String? title, {String? message}) async {
    assert(
      _tokenBeginRequest == null,
      'Begin should not be called more than once',
    );

    // Put the create/begin into a future so if end() is called before the
    // begin is sent (which could happen because create is async), end will
    // not be sent/return too early.
    _tokenBeginRequest = _server
        .sendLspRequest(
          Method.window_workDoneProgress_create,
          WorkDoneProgressCreateParams(token: _token),
        )
        .then((response) {
          // If the client did not create a token, do not send begin (and signal
          // that we should also not send end).
          if (response.error != null) return false;
          super.begin(title, message: message);
          return true;
        });

    await _tokenBeginRequest;
  }

  @override
  Future<void> end([String? message]) async {
    // Only end the token after both create/begin have completed, and return
    // a Future to indicate that has happened to callers know when it's safe
    // to re-use the token identifier.
    var beginRequest = _tokenBeginRequest;
    if (beginRequest != null) {
      var didBegin = await beginRequest;
      if (didBegin) {
        super.end(message);
      }
      _tokenBeginRequest = null;
    }
  }

  static String _randomTokenIdentifier() {
    var millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
    var random = _random.nextInt(0x3fffffff);
    return '$millisecondsSinceEpoch$random';
  }
}

class _TokenProgressReporter extends ProgressReporter {
  final LspAnalysisServer _server;
  final ProgressToken _token;
  bool _needsEnd = false;

  new(this._server, this._token) : super._();

  @override
  void begin(String? title, {String? message}) {
    _needsEnd = true;
    _sendNotification(
      WorkDoneProgressBegin(title: title ?? 'Working…', message: message),
    );
  }

  @override
  void end([String? message]) {
    if (!_needsEnd) return;
    _needsEnd = false;
    _sendNotification(WorkDoneProgressEnd(message: message));
  }

  void _sendNotification(ToJsonable value) {
    _server.sendLspNotification(
      NotificationMessage(
        method: Method.progress,
        params: ProgressParams(token: _token, value: value),
        jsonrpc: jsonRpcVersion,
      ),
    );
  }
}
