// 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:nnbd_migration/src/hint_action.dart';

/// Information about what should be populated into the "Edit Details" view of
/// the migration preview tool.
class EditDetails {
  /// A list of edits that can be offered to the user related to this source
  /// location (e.g. adding/removing hints).  `null` if this feature is
  /// disabled.
  final List<EditLink>? edits;

  /// A string explanation of the edit.
  final String? explanation;

  /// The line number of the edit.
  final int? line;

  /// The path of the file that was edited, to be shown to the user.
  final String? displayPath;

  /// The path of the file that was edited, as a URI.
  final String? uriPath;

  /// A list of traces representing stacktrace-like views of why the change was
  /// made, or the empty list if there are no traces for this change.
  final List<Trace>? traces;

  EditDetails(
      {this.edits,
      required this.explanation,
      required this.line,
      required this.displayPath,
      required this.uriPath,
      this.traces = const []});

  EditDetails.fromJson(dynamic json)
      : edits = _decodeEdits(json['edits'] as List<Object?>?),
        explanation = json['explanation'] as String?,
        line = json['line'] as int?,
        displayPath = json['displayPath'] as String?,
        uriPath = json['uriPath'] as String?,
        traces = _decodeTraces(json['traces'] as List<Object?>?);

  Map<String, Object?> toJson() => {
        if (edits != null) 'edits': [for (var edit in edits!) edit.toJson()],
        'explanation': explanation,
        'line': line,
        'displayPath': displayPath,
        'uriPath': uriPath,
        if (traces != null)
          'traces': [for (var trace in traces!) trace.toJson()],
      };

  static List<EditLink>? _decodeEdits(List<Object?>? json) =>
      json == null ? null : [for (var edit in json) EditLink.fromJson(edit)];

  static List<Trace>? _decodeTraces(List<Object?>? json) =>
      json == null ? null : [for (var trace in json) Trace.fromJson(trace)];
}

/// Information about a single link that should be included in the
/// "Edit Details" view of the migration preview tool, where the purpose of the
/// link is to allow the user to make a change to the source file (e.g. to add
/// or remove a hint).
class EditLink {
  /// Description of the change to be performed.
  final String? description;

  /// The href to link to.
  final String? href;

  EditLink({required this.description, required this.href});

  EditLink.fromJson(dynamic json)
      : description = json['description'] as String?,
        href = json['href'] as String?;

  Map<String, Object?> toJson() => {
        'description': description,
        'href': href,
      };
}

/// Information about a single link that should be included in the
/// "Edit Details" view of the migration preview tool, where the purpose of the
/// link is to allow the user to navigate to a source file containing
/// information about the rationale for a change.
class TargetLink {
  /// The href to link to.
  final String? href;

  /// The line number of the link.
  final int? line;

  /// Relative path to the source file (intended for display).
  final String? path;

  TargetLink({required this.href, required this.line, required this.path});

  TargetLink.fromJson(dynamic json)
      : href = json['href'] as String?,
        line = json['line'] as int?,
        path = json['path'] as String?;

  Map<String, Object?> toJson() => {
        'href': href,
        'line': line,
        'path': path,
      };
}

/// A trace of why a nullability decision was made.
class Trace {
  /// Text description of the trace.
  final String? description;

  /// List of trace entries.
  final List<TraceEntry> entries;

  Trace({required this.description, required this.entries});

  Trace.fromJson(dynamic json)
      : description = json['description'] as String?,
        entries = [
          for (var entry in json['entries'] as List<Object?>)
            TraceEntry.fromJson(entry)
        ];

  Map<String, Object?> toJson() => {
        'description': description,
        'entries': [for (var entry in entries) entry.toJson()]
      };
}

/// Information about a single entry in a nullability trace.
class TraceEntry {
  /// Text description of the entry.
  final String? description;

  /// The function associated with the entry.  We display this before the link
  /// so that the trace has the familiar appearance of a stacktrace.
  ///
  /// Null if not known.
  final String? function;

  /// Source code location associated with the entry, or `null` if no source
  /// code location is known.
  final TargetLink? link;

  /// The hint actions available to affect this entry of the trace, or `[]` if
  /// none.
  final List<HintAction> hintActions;

  TraceEntry(
      {required this.description,
      this.function,
      this.link,
      this.hintActions = const []});

  TraceEntry.fromJson(dynamic json)
      : description = json['description'] as String?,
        function = json['function'] as String?,
        link = _decodeLink(json['link']),
        hintActions = (json['hintActions'] as List?)
                ?.map((value) =>
                    HintAction.fromJson(value as Map<String, Object?>))
                .toList() ??
            const [];

  Map<String, Object?> toJson() => {
        'description': description,
        if (function != null) 'function': function,
        if (link != null) 'link': link!.toJson(),
        if (hintActions.isNotEmpty)
          'hintActions': hintActions.map((action) => action.toJson()).toList()
      };

  static TargetLink? _decodeLink(dynamic json) =>
      json == null ? null : TargetLink.fromJson(json);
}
