// Copyright (c) 2025, 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.

part of 'api.dart';

/// This request is sent from the client to the server when it first connects,
/// asking it to begin initialization.
extension type InitializeRequest._fromMap(Map<String, Object?> _value)
    implements Request {
  static const methodName = 'initialize';

  factory InitializeRequest({
    required ProtocolVersion protocolVersion,
    required ClientCapabilities capabilities,
    required ClientImplementation clientInfo,
    MetaWithProgressToken? meta,
  }) => InitializeRequest._fromMap({
    'protocolVersion': protocolVersion.versionString,
    'capabilities': capabilities,
    'clientInfo': clientInfo,
    if (meta != null) '_meta': meta,
  });

  /// The latest version of the Model Context Protocol that the client supports.
  ///
  /// The client MAY decide to support older versions as well.
  ///
  /// May be `null` if the version is not recognized.
  ProtocolVersion? get protocolVersion =>
      ProtocolVersion.tryParse(_value['protocolVersion'] as String);

  ClientCapabilities get capabilities =>
      _value['capabilities'] as ClientCapabilities;

  ClientImplementation get clientInfo =>
      _value['clientInfo'] as ClientImplementation;
}

/// After receiving an initialize request from the client, the server sends
/// this response.
extension type InitializeResult.fromMap(Map<String, Object?> _value)
    implements Result {
  factory InitializeResult({
    required ProtocolVersion protocolVersion,
    required ServerCapabilities serverCapabilities,
    required ServerImplementation serverInfo,
    String? instructions,
  }) => InitializeResult.fromMap({
    'protocolVersion': protocolVersion.versionString,
    'capabilities': serverCapabilities,
    'serverInfo': serverInfo,
    'instructions': instructions,
  });

  /// The version of the Model Context Protocol that the server wants to use.
  ///
  /// This may not match the version that the client requested. If the client
  /// cannot support this version, it MUST disconnect.
  ///
  /// May be `null` if the version is not recognized.
  ProtocolVersion? get protocolVersion =>
      ProtocolVersion.tryParse(_value['protocolVersion'] as String);

  /// Sets the protocol version, by default this is set for you, but you can
  /// override it to a specific version if desired.
  ///
  /// While this API is typed as nullable, `null` is not an allowed value.
  set protocolVersion(ProtocolVersion? value) {
    assert(value != null);
    _value['protocolVersion'] = value!.versionString;
  }

  ServerCapabilities get capabilities =>
      _value['capabilities'] as ServerCapabilities;

  ServerImplementation get serverInfo =>
      _value['serverInfo'] as ServerImplementation;

  /// Instructions describing how to use the server and its features.
  ///
  /// This can be used by clients to improve the LLM's understanding of
  /// available tools, resources, etc. It can be thought of like a "hint" to the
  /// model. For example, this information MAY be added to the system prompt.
  String? get instructions => _value['instructions'] as String?;
}

/// This notification is sent from the client to the server after initialization
/// has finished.
extension type InitializedNotification.fromMap(Map<String, Object?> _value)
    implements Notification {
  static const methodName = 'notifications/initialized';

  factory InitializedNotification({Meta? meta}) =>
      InitializedNotification.fromMap({if (meta != null) '_meta': meta});
}

/// Capabilities a client may support.
///
/// Known capabilities are defined here, in this schema, but this is not a
/// closed set: any client can define its own, additional capabilities.
extension type ClientCapabilities.fromMap(Map<String, Object?> _value) {
  factory ClientCapabilities({
    Map<String, Object?>? experimental,
    RootsCapabilities? roots,
    Map<String, Object?>? sampling,
  }) => ClientCapabilities.fromMap({
    if (experimental != null) 'experimental': experimental,
    if (roots != null) 'roots': roots,
    if (sampling != null) 'sampling': sampling,
  });

  /// Experimental, non-standard capabilities that the client supports.
  Map<String, Object?>? get experimental =>
      _value['experimental'] as Map<String, Object?>?;

  /// Sets [experimental] asserting it is non-null first.
  set experimental(Map<String, Object?>? value) {
    assert(experimental == null);
    _value['experimental'] = value;
  }

  /// Present if the client supports any capabilities regarding roots.
  RootsCapabilities? get roots => _value['roots'] as RootsCapabilities?;

  /// Sets [roots] asserting it is non-null first.
  set roots(RootsCapabilities? value) {
    assert(roots == null);
    _value['roots'] = value;
  }

  /// Present if the client supports sampling from an LLM.
  Map<String, Object?>? get sampling =>
      (_value['sampling'] as Map?)?.cast<String, Object?>();

  /// Sets [sampling] asserting it is non-null first.
  set sampling(Map<String, Object?>? value) {
    assert(sampling == null);
    _value['sampling'] = value;
  }
}

/// Whether the client supports notifications for changes to the roots list.
extension type RootsCapabilities.fromMap(Map<String, Object?> _value) {
  factory RootsCapabilities({bool? listChanged}) => RootsCapabilities.fromMap({
    if (listChanged != null) 'listChanged': listChanged,
  });

  /// Present if the client supports listing roots.
  bool? get listChanged => _value['listChanged'] as bool?;

  /// Sets whether [listChanged] is supported.
  set listChanged(bool? value) {
    assert(listChanged == null);
    _value['listChanged'] = value;
  }
}

/// Capabilities that a server may support.
///
/// Known capabilities are defined here, in this schema, but this is not a
/// closed set: any server can define its own, additional capabilities.
extension type ServerCapabilities.fromMap(Map<String, Object?> _value) {
  factory ServerCapabilities({
    Map<String, Object?>? experimental,
    Completions? completions,
    Logging? logging,
    Prompts? prompts,
    Resources? resources,
    Tools? tools,
  }) => ServerCapabilities.fromMap({
    if (experimental != null) 'experimental': experimental,
    if (logging != null) 'logging': logging,
    if (prompts != null) 'prompts': prompts,
    if (resources != null) 'resources': resources,
    if (tools != null) 'tools': tools,
  });

  /// Experimental, non-standard capabilities that the server supports.
  Map<String, Object?>? get experimental =>
      (_value['experimental'] as Map?)?.cast<String, Object?>();

  /// Sets [experimental] if it is null, otherwise throws.
  set experimental(Map<String, Object?>? value) {
    assert(experimental == null);
    _value['experimental'] = value;
  }

  /// Present if the server supports sending completion requests to the client.
  Completions? get completions => _value['completions'] as Completions?;

  /// Sets [completions] if it is null, otherwise throws.
  set completions(Completions? value) {
    assert(completions == null);
    _value['completions'] = value;
  }

  /// Present if the server supports sending log messages to the client.
  Logging? get logging =>
      (_value['logging'] as Map?)?.cast<String, Object?>() as Logging?;

  /// Sets [logging] if it is null, otherwise throws.
  set logging(Logging? value) {
    assert(logging == null);
    _value['logging'] = value;
  }

  /// Present if the server offers any prompt templates.
  Prompts? get prompts => _value['prompts'] as Prompts?;

  /// Sets [prompts] if it is null, otherwise throws.
  set prompts(Prompts? value) {
    assert(prompts == null);
    _value['prompts'] = value;
  }

  /// Whether this server supports subscribing to resource updates.
  Resources? get resources => _value['resources'] as Resources?;

  /// Sets [resources] if it is null, otherwise throws.
  set resources(Resources? value) {
    assert(resources == null);
    _value['resources'] = value;
  }

  /// Present if the server offers any tools to call.
  Tools? get tools => _value['tools'] as Tools?;

  /// Sets [tools] if it is null, otherwise throws.
  set tools(Tools? value) {
    assert(tools == null);
    _value['tools'] = value;
  }
}

/// Completions parameter for [ServerCapabilities].
extension type Completions.fromMap(Map<String, Object?> _value) {
  factory Completions() => Completions.fromMap({});
}

/// Prompts parameter for [ServerCapabilities].
extension type Prompts.fromMap(Map<String, Object?> _value) {
  factory Prompts({bool? listChanged}) =>
      Prompts.fromMap({if (listChanged != null) 'listChanged': listChanged});

  /// Whether this server supports notifications for changes to the prompt list.
  bool? get listChanged => _value['listChanged'] as bool?;

  /// Sets whether [listChanged] is supported.
  set listChanged(bool? value) {
    assert(listChanged == null);
    _value['listChanged'] = value;
  }
}

/// Resources parameter for [ServerCapabilities].
extension type Resources.fromMap(Map<String, Object?> _value) {
  factory Resources({bool? listChanged, bool? subscribe}) => Resources.fromMap({
    if (listChanged != null) 'listChanged': listChanged,
    if (subscribe != null) 'subscribe': subscribe,
  });

  /// Whether this server supports notifications for changes to the resource
  /// list.
  bool? get listChanged => _value['listChanged'] as bool?;

  /// Sets whether [listChanged] is supported.
  set listChanged(bool? value) {
    assert(listChanged == null);
    _value['listChanged'] = value;
  }

  /// Present if the server offers any resources to read.
  bool? get subscribe => _value['subscribe'] as bool?;

  /// Sets whether [subscribe] is supported.
  set subscribe(bool? value) {
    assert(subscribe == null);
    _value['subscribe'] = value;
  }
}

/// Tools parameter for [ServerCapabilities].
extension type Tools.fromMap(Map<String, Object?> _value) {
  factory Tools({bool? listChanged}) =>
      Tools.fromMap({if (listChanged != null) 'listChanged': listChanged});

  /// Whether this server supports notifications for changes to the tool list.
  bool? get listChanged => _value['listChanged'] as bool?;

  /// Sets whether [listChanged] is supported.
  set listChanged(bool? value) {
    assert(listChanged == null);
    _value['listChanged'] = value;
  }
}

/// Describes the name and version of an MCP client implementation.
extension type ClientImplementation.fromMap(Map<String, Object?> _value) {
  factory ClientImplementation({
    required String name,
    required String version,
  }) => ClientImplementation.fromMap({'name': name, 'version': version});

  String get name => _value['name'] as String;
  String get version => _value['version'] as String;
}

/// Describes the name and version of an MCP server implementation.
extension type ServerImplementation.fromMap(Map<String, Object?> _value) {
  factory ServerImplementation({
    required String name,
    required String version,
  }) => ServerImplementation.fromMap({'name': name, 'version': version});

  String get name => _value['name'] as String;
  String get version => _value['version'] as String;
}
