// 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 'package:collection/collection.dart';
import 'package:path/path.dart' as path;

/// Provides access to both global and resource-specific client configuration.
///
/// Resource-specific config is currently only supported at the WorkspaceFolder
/// level so when looking up config for a resource, the nearest WorkspaceFolders
/// config will be used.
class LspClientConfiguration {
  /// Global settings for the workspace.
  ///
  /// Used as a fallback for resource settings if no specific config is found
  /// for the resource.
  LspGlobalClientConfiguration _globalSettings =
      LspGlobalClientConfiguration({});

  /// Settings for each resource.
  ///
  /// Keys are string paths without trailing path separators (eg. 'C:\foo').
  final Map<String, LspResourceClientConfiguration> _resourceSettings =
      <String, LspResourceClientConfiguration>{};

  /// Pattern for stripping trailing slashes that may be been provided by the
  /// client (in WorkspaceFolder URIs) for consistent comparisons.
  final _trailingSlashPattern = RegExp(r'[\/]+$');

  /// Returns the global configuration for the whole workspace.
  LspGlobalClientConfiguration get global => _globalSettings;

  /// Returns whether or not the provided new configuration changes any values
  /// that would require analysis roots to be updated.
  bool affectsAnalysisRoots(LspGlobalClientConfiguration otherConfig) {
    return _globalSettings.analysisExcludedFolders !=
        otherConfig.analysisExcludedFolders;
  }

  /// Returns config for a given resource.
  ///
  /// Because we only support config at the WorkspaceFolder level, this is done
  /// by finding the nearest WorkspaceFolder to [resourcePath] and using config
  /// for that.
  ///
  /// If no specific config is available, returns [global].
  LspResourceClientConfiguration forResource(String resourcePath) {
    final workspaceFolder = _getWorkspaceFolderPath(resourcePath);

    if (workspaceFolder == null) {
      return _globalSettings;
    }

    return _resourceSettings[_normaliseFolderPath(workspaceFolder)] ??
        _globalSettings;
  }

  /// Replaces all previously known configuration with updated values from the
  /// client.
  void replace(
    Map<String, Object?> globalConfig,
    Map<String, Map<String, Object?>> workspaceFolderConfig,
  ) {
    _globalSettings = LspGlobalClientConfiguration(globalConfig);

    _resourceSettings
      ..clear()
      ..addAll(workspaceFolderConfig.map(
        (key, value) => MapEntry(
          _normaliseFolderPath(key),
          LspResourceClientConfiguration(value, _globalSettings),
        ),
      ));
  }

  /// Gets the path for the WorkspaceFolder closest to [resourcePath].
  String? _getWorkspaceFolderPath(String resourcePath) {
    final candidates = _resourceSettings.keys
        .where((wfPath) =>
            wfPath == _normaliseFolderPath(resourcePath) ||
            path.isWithin(wfPath, resourcePath))
        .toList();
    candidates.sort((a, b) => -a.length.compareTo(b.length));
    return candidates.firstOrNull;
  }

  /// Normalises a folder path to never have a trailing path separator.
  String _normaliseFolderPath(String path) =>
      path.replaceAll(_trailingSlashPattern, '');
}

/// Wraps the client (editor) configuration to provide stronger typing and
/// handling of default values where a setting has not been supplied.
///
/// Settings in this class are only allowed to be configured at the workspace
/// level (they will be ignored at the resource level).
class LspGlobalClientConfiguration extends LspResourceClientConfiguration {
  LspGlobalClientConfiguration(Map<String, Object?> settings)
      : super(settings, null);

  List<String> get analysisExcludedFolders {
    // This setting is documented as a string array, but because editors are
    // unlikely to provide validation, support single strings for convenience.
    final value = _settings['analysisExcludedFolders'];
    if (value is String) {
      return [value];
    } else if (value is List && value.every((s) => s is String)) {
      return value.cast<String>();
    } else {
      return const [];
    }
  }

  /// Whether methods/functions in completion should include parens and argument
  /// placeholders when used in an invocation context.
  bool get completeFunctionCalls =>
      _settings['completeFunctionCalls'] as bool? ?? false;

  /// A preview flag for enabling commit characters for completions.
  ///
  /// This is a temporary setting to allow this feature to be tested without
  /// defaulting to on for everybody.
  bool get previewCommitCharacters =>
      _settings['previewCommitCharacters'] as bool? ?? false;

  /// Whether diagnostics should be generated for TODO comments.
  bool get showTodos => _settings['showTodos'] as bool? ?? false;
}

/// Wraps the client (editor) configuration for a specific resource.
///
/// Settings in this class are only allowed to be configured either for a
/// resource or for the whole workspace.
///
/// Right now, we treat "resource" to always mean a WorkspaceFolder since no
/// known editors allow per-file configuration and it allows us to keep the
/// settings cached, invalidated only when WorkspaceFolders change.
class LspResourceClientConfiguration {
  final Map<String, Object?> _settings;
  final LspResourceClientConfiguration? _fallback;

  LspResourceClientConfiguration(this._settings, this._fallback);

  /// Whether to enable the SDK formatter.
  ///
  /// If this setting is `false`, the formatter will be unregistered with the
  /// client.
  bool get enableSdkFormatter =>
      _settings['enableSdkFormatter'] as bool? ??
      _fallback?.enableSdkFormatter ??
      true;

  /// The line length used when formatting documents.
  ///
  /// If null, the formatters default will be used.
  int? get lineLength =>
      _settings['lineLength'] as int? ?? _fallback?.lineLength;
}
