// 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_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.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 ProgressReporter.clientProvided(
          LspAnalysisServer server, Either2<int, String> 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 ProgressReporter.serverCreated(LspAnalysisServer server,
          [Either2<int, String>? token]) =>
      _ServerCreatedProgressReporter(server, token);

  ProgressReporter._();

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

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

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

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

  _ServerCreatedProgressReporter(
    LspAnalysisServer server,
    Either2<int, String>? token,
  ) : super(
          server,
          token ?? Either2<int, String>.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
        .sendRequest(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.
    final beginRequest = _tokenBeginRequest;
    if (beginRequest != null) {
      final didBegin = await beginRequest;
      if (didBegin) {
        super.end(message);
      }
      _tokenBeginRequest = null;
    }
  }

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

class _TokenProgressReporter extends ProgressReporter {
  final LspAnalysisServer _server;
  final Either2<int, String> _token;
  bool _needsEnd = false;

  _TokenProgressReporter(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) async {
    _server.sendNotification(NotificationMessage(
        method: Method.progress,
        params: ProgressParams(
          token: _token,
          value: value,
        ),
        jsonrpc: jsonRpcVersion));
  }
}
