// Copyright (c) 2023, 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:vm_service/vm_service.dart';

import 'protocol_generated.dart';

/// A wrapper around variables for use in `variablesRequest` that can hold
/// additional data, such as a formatting information supplied in an evaluation
/// request.
class VariableData {
  final Object data;
  final VariableFormat? format;

  VariableData(this.data, this.format);
}

/// A wrapper around variables for use in `variablesRequest` that can hold
/// additional data, such as a formatting information supplied in an evaluation
/// request.
class FrameScopeData {
  final Frame frame;
  final FrameScopeDataKind kind;

  FrameScopeData(this.frame, this.kind);
}

enum FrameScopeDataKind {
  locals,
  globals,
}

/// A wrapper around a variable for use in `variablesRequest` that holds
/// an instance sent for inspection.
class InspectData {
  final InstanceRef? instance;

  InspectData(this.instance);
}

/// Formatting preferences for a variable.
class VariableFormat {
  /// Whether to supress quotes around [String]s.
  final bool noQuotes;

  /// Whether to render integers as hex.
  final bool hex;

  /// Whether to force rendering integers as decimal (base 10).
  final bool decimal;

  const VariableFormat({
    this.noQuotes = false,
    this.hex = false,
    this.decimal = false,
  });

  const VariableFormat.noQuotes() : this(noQuotes: true);
  const VariableFormat.hex() : this(hex: true);

  String formatInt(int? value) {
    return value != null && hex
        ? '0x${value.toRadixString(16)}'
        : value.toString();
  }

  String formatString(String value) {
    return noQuotes ? value : '"$value"';
  }

  /// Converts a DAP ValueFormat into our own formatting class used by our
  /// debug adapters.
  ///
  /// Returns `null` if the desired format does not require special handling
  /// (or is something we don't support).
  static VariableFormat? fromDapValueFormat(ValueFormat? format) {
    return (format?.hex ?? false) ? VariableFormat.hex() : null;
  }
}

/// An evaluation expression and optional formatting preferences that were
/// supplied as a trailing format specifier in expression evaluations.
class EvaluationExpression {
  final String expression;
  final VariableFormat? format;

  EvaluationExpression._(this.expression, {this.format});

  /// A regular expression that extracts format specifiers from an evaluation
  /// expression.
  static final _expressionWithFormatSpecifierRegex =
      RegExp(r'(.*?)(?:,([\w,]+))$');

  /// Parse an expression that may end with a format specifier to dictate the
  /// format a value should be presented in.
  factory EvaluationExpression.parse(String expression) {
    final match = _expressionWithFormatSpecifierRegex.firstMatch(expression);
    expression = match?.group(1) ?? expression;
    final formatSpecifiers = match?.group(2)?.split(',').toSet() ?? const {};
    final format = formatSpecifiers.isEmpty
        ? null
        : VariableFormat(
            noQuotes: formatSpecifiers.contains('nq'),
            hex: formatSpecifiers.contains('h'),
            decimal: formatSpecifiers.contains('d'),
          );

    return EvaluationExpression._(expression, format: format);
  }
}
