// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is hand-formatted.

// This file must not import `dart:ui`, directly or indirectly, as it is
// intended to function even in pure Dart server or CLI environments.
import 'package:meta/meta.dart';

/// A map whose keys are strings and whose values are [DynamicMap],
/// [DynamicList], int, double, bool, string, and [BlobNode] objects.
///
/// Part of the data type for [DynamicContent] objects.
typedef DynamicMap = Map<String, Object?>;

/// A list whose values are [DynamicMap], [DynamicList], int, double, bool,
/// string, and [BlobNode] objects.
///
/// Part of the data type for [DynamicContent] objects.
typedef DynamicList = List<Object?>;

/// Base class of nodes that appear in the output of [decodeDataBlob] and
/// [decodeLibraryBlob].
///
/// In addition to this, the following types can be found in that output:
///
///  * [DynamicMap]
///  * [DynamicList]
///  * [int]
///  * [double]
///  * [bool]
///  * [String]
abstract class BlobNode {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const BlobNode();
}

bool _listEquals<T>(List<T>? a, List<T>? b) {
  if (identical(a, b)) {
    return true;
  }
  if (a == null || b == null || a.length != b.length) {
    return false;
  }
  for (int index = 0; index < a.length; index += 1) {
    if (a[index] != b[index]) {
      return false;
    }
  }
  return true;
}

/// The name of a widgets library in the RFW package.
///
/// Libraries are typically referred to with names like "core.widgets" or
/// "com.example.shopping.cart". This class represents these names as lists of
/// tokens, in those cases `['core', 'widgets']` and `['com', 'example',
/// 'shopping', 'cart']`, for example.
@immutable
class LibraryName implements Comparable<LibraryName> {
  /// Wrap the given list as a [LibraryName].
  ///
  /// The given list is not copied; it is an error to modify it after creating
  /// the [LibraryName].
  const LibraryName(this.parts);

  /// The components of the structured library name.
  final List<String> parts;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is LibraryName
        && _listEquals<String>(parts, other.parts);
  }

  @override
  int get hashCode => Object.hashAll(parts);

  @override
  String toString() => parts.join('.');

  @override
  int compareTo(LibraryName other) {
    for (int index = 0; index < parts.length; index += 1) {
      if (other.parts.length <= index) {
        return 1;
      }
      final int result = parts[index].compareTo(other.parts[index]);
      if (result != 0) {
        return result;
      }
    }
    assert(other.parts.length >= parts.length);
    return parts.length - other.parts.length;
  }
}

/// The name of a widget used by the RFW package, including its library name.
///
/// This can be used to identify both local widgets and remote widgets.
@immutable
class FullyQualifiedWidgetName implements Comparable<FullyQualifiedWidgetName> {
  /// Wrap the given library name and widget name in a [FullyQualifiedWidgetName].
  const FullyQualifiedWidgetName(this.library, this.widget);

  /// The name of the library in which [widget] can be found.
  final LibraryName library;

  /// The name of the widget, which should be in the specified [library].
  final String widget;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FullyQualifiedWidgetName
        && library == other.library && widget == other.widget;
  }

  @override
  int get hashCode => Object.hash(library, widget);

  @override
  String toString() => '$library:$widget';

  @override
  int compareTo(FullyQualifiedWidgetName other) {
    final int result = library.compareTo(other.library);
    if (result != 0) {
      return result;
    }
    return widget.compareTo(other.widget);
  }
}

/// The type of the [missing] value.
///
/// This is used internally by the RFW package to avoid needing to use nullable
/// types.
class Missing extends BlobNode {
  const Missing._();

  @override
  String toString() => '<missing>';
}

/// The value used by [DynamicContent] to represent missing data.
///
/// This is return from [DynamicContent.subscribe] when the specified key is not
/// present.
///
/// Content in a [DynamicContent] should not contain [missing] values.
const Missing missing = Missing._();

/// Representation of the `...for` construct in Remote Flutter Widgets library
/// blobs.
class Loop extends BlobNode {
  /// Creates a [Loop] with the given [input] and [output].
  ///
  /// The provided objects must not be mutated after being given to the
  /// constructor (e.g. the ownership of any lists and maps passes to this
  /// object).
  const Loop(this.input, this.output);

  /// The list on which to iterate.
  ///
  /// This is typically some sort of [Reference], but could be a [DynamicList].
  ///
  /// It is an error for this to be a value that does not resolve to a list.
  final Object input;

  /// The template to apply for each value on [input].
  final Object output;

  @override
  String toString() => '...for loop in $input: $output';
}

/// Representation of the `switch` construct in Remote Flutter Widgets library
/// blobs.
class Switch extends BlobNode {
  /// Creates a [Switch] with the given [input] and [outputs].
  ///
  /// The provided objects must not be mutated after being given to the
  /// constructor. In particular, changing the [outputs] map after creating the
  /// [Switch] is an error.
  const Switch(this.input, this.outputs);

  /// The value to switch on (after resolution).
  final Object input;

  /// The cases for this switch. Keys correspond to values to compare with
  /// [input]. The null value is used as the default case.
  ///
  /// At runtime, if none of the keys match [input] and there is no null key,
  /// the [Switch] as a whole is treated as if it was [missing]. If the [Switch]
  /// is used where a [ConstructorCall] was expected, the result is an
  /// [ErrorWidget].
  final Map<Object?, Object> outputs;

  @override
  String toString() => 'switch $input $outputs';
}

/// Representation of references to widgets in Remote Flutter Widgets library
/// blobs.
class ConstructorCall extends BlobNode {
  /// Creates a [ConstructorCall] for a widget of the given name in the current
  /// library's scope, with the given [arguments].
  ///
  /// The [arguments] must not be mutated after the object is created.
  const ConstructorCall(this.name, this.arguments);

  /// The name of the widget to create.
  ///
  /// The name is looked up in the current library, or, failing that, in a
  /// depth-first search of this library's dependencies.
  final String name;

  /// The arguments to pass to the constructor.
  ///
  /// Constructors in RFW only have named arguments. This differs from Dart
  /// (where arguments can also be positional.)
  final DynamicMap arguments;

  @override
  String toString() => '$name($arguments)';
}

/// Base class for various kinds of references in the RFW data structures.
abstract class Reference extends BlobNode {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  ///
  /// The [parts] must not be mutated after the object is created.
  const Reference(this.parts);

  /// The components of the reference. Each entry must be either a String (to
  /// index into a [DynamicMap]) an integer (to index into a [DynamicList]).
  ///
  /// It is an error for any of the parts to be of any other type.
  final List<Object> parts;
}

/// Unbound reference to arguments.
///
/// This class is used to represent references of the form "args.foo.bar" after
/// parsing, before the arguments are bound.
class ArgsReference extends Reference {
  /// Wraps the given [parts] as an [ArgsReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  const ArgsReference(List<Object> parts): super(parts);

  /// Binds the arguments reference to a specific set of arguments.
  ///
  /// Returns a [BoundArgsReference] with the same [parts] and whose
  /// [BoundArgsReference.arguments] is given by `arguments`.
  BoundArgsReference bind(Object arguments) {
    return BoundArgsReference(arguments, parts);
  }

  @override
  String toString() => 'args.${parts.join(".")}';
}

/// Bound reference to arguments.
///
/// This class is used to represent references of the form "args.foo.bar" after
/// a widget declaration has been bound to specific arguments via a constructor
/// call. The [arguments] property is a reference to the
/// [ConstructorCall.arguments] object (or, more typically, a clone of that
/// object that itself has had references within it bound).
///
/// This class is an internal detail of the RFW [Runtime] and is generally not
/// used directly.
class BoundArgsReference extends Reference {
  /// Wraps the given [parts] and [arguments] as an [ArgsReference].
  ///
  /// The parameters must not be mutated after the object is created.
  ///
  /// Generally this class is created using [ArgsReference.bind].
  const BoundArgsReference(this.arguments, List<Object> parts): super(parts);

  /// The object into which [parts] will be indexed.
  ///
  /// This could contain [Loop]s, which is why it cannot be indexed immediately
  /// upon creation.
  final Object arguments;

  @override
  String toString() => 'args($arguments).${parts.join(".")}';
}

/// Reference to the [DynamicContent] data that is passed into the widget (see
/// [Runtime.build]'s `data` argument).
class DataReference extends Reference {
  /// Wraps the given [parts] as an [DataReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  const DataReference(List<Object> parts): super(parts);

  /// Creates a new [DataRefererence] that indexes even deeper than this one.
  ///
  /// For example, suppose a widget's arguments consisted of a map with one key,
  /// "a", whose value was a [DataRefererence] referencing "data.foo.bar". Now
  /// suppose that the widget itself has an [ArgsReference] that references
  /// "args.a.baz". The "args.a" part identifies the aforementioned
  /// [DataReference], and so the resulting reference is actually to
  /// "data.foo.bar.baz".
  ///
  /// In this example, the [DataReference] to "data.foo.bar" would have its
  /// [constructReference] method invoked by the runtime, with `["baz"]` as the
  /// `moreParts` argument, so that the resulting [DataReference]'s [parts] is a
  /// combination of the original's (`["foo", "bar"]`) and the additional parts
  /// provided to the method.
  DataReference constructReference(List<Object> moreParts) {
    return DataReference(parts + moreParts);
  }

  @override
  String toString() => 'data.${parts.join(".")}';
}

/// Unbound reference to a [Loop].
class LoopReference extends Reference {
  /// Wraps the given [loop] and [parts] as a [LoopReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  const LoopReference(this.loop, List<Object> parts): super(parts);

  /// The index to the referenced loop.
  ///
  /// Loop indices count up, so the nearest loop ancestor of the reference has
  /// index zero, with indices counting up when going up the tree towards the
  /// root.
  final int loop; // this is basically a De Bruijn index

  /// Creates a new [LoopRefererence] that indexes even deeper than this one.
  ///
  /// For example, suppose a widget's arguments consisted of a map with one key,
  /// "a", whose value was a [LoopRefererence] referencing "loop0.foo.bar". Now
  /// suppose that the widget itself has an [ArgsReference] that references
  /// "args.a.baz". The "args.a" part identifies the aforementioned
  /// [LoopReference], and so the resulting reference is actually to
  /// "data.foo.bar.baz".
  ///
  /// In this example, the [LoopReference] to "loop0.foo.bar" would have its
  /// [constructReference] method invoked by the runtime, with `["baz"]` as the
  /// `moreParts` argument, so that the resulting [LoopReference]'s [parts] is a
  /// combination of the original's (`["foo", "bar"]`) and the additional parts
  /// provided to the method.
  ///
  /// The [loop] index is maintained in the new object.
  LoopReference constructReference(List<Object> moreParts) {
    return LoopReference(loop, parts + moreParts);
  }

  /// Binds the loop reference to a specific value.
  ///
  /// Returns a [BoundLoopReference] with the same [parts] and whose
  /// [BoundLoopReference.value] is given by `value`. The [loop] index is
  /// dropped in the process.
  BoundLoopReference bind(Object value) {
    return BoundLoopReference(value, parts);
  }

  @override
  String toString() => 'loop$loop.${parts.join(".")}';
}

/// Bound reference to a [Loop].
///
/// This class is used to represent references of the form "loopvar.foo.bar"
/// after the list containing the relevant loop has been dereferenced so that
/// the loop variable refers to a specific value in the list. The [value] is
/// that resolved value.
///
/// This class is an internal detail of the RFW [Runtime] and is generally not
/// used directly.
class BoundLoopReference extends Reference {
  /// Wraps the given [value] and [parts] as a [BoundLoopReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  ///
  /// Generally this class is created using [LoopReference.bind].
  const BoundLoopReference(this.value, List<Object> parts): super(parts);

  /// The object into which [parts] will index.
  ///
  /// This could contain further [Loop]s or unbound [LoopReference]s, which is
  /// why it cannot be indexed immediately upon creation.
  final Object value;

  /// Creates a new [BoundLoopRefererence] that indexes even deeper than this
  /// one.
  ///
  /// For example, suppose a widget's arguments consisted of a map with one key,
  /// "a", whose value was a [BoundLoopRefererence] referencing "loop0.foo.bar".
  /// Now suppose that the widget itself has an [ArgsReference] that references
  /// "args.a.baz". The "args.a" part identifies the aforementioned
  /// [BoundLoopReference], and so the resulting reference is actually to
  /// "data.foo.bar.baz".
  ///
  /// In this example, the [BoundLoopReference] to "loop0.foo.bar" would have
  /// its [constructReference] method invoked by the runtime, with `["baz"]` as
  /// the `moreParts` argument, so that the resulting [BoundLoopReference]'s
  /// [parts] is a combination of the original's (`["foo", "bar"]`) and the
  /// additional parts provided to the method.
  ///
  /// The resolved [value] (which is what the [parts] will eventually index
  /// into) is maintained in the new object.
  BoundLoopReference constructReference(List<Object> moreParts) {
    return BoundLoopReference(value, parts + moreParts);
  }

  @override
  String toString() => 'loop($value).${parts.join(".")}';
}

/// Base class for [StateReference] and [BoundStateReference].
///
/// This is used to ensure [SetStateHandler]'s [SetStateHandler.stateReference]
/// property can only hold a state reference.
abstract class AnyStateReference extends Reference {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  ///
  /// The [parts] must not be mutated after the object is created.
  const AnyStateReference(List<Object> parts): super(parts);
}

/// Unbound reference to remote widget's state.
///
/// This class is used to represent references of the form "state.foo.bar".
class StateReference extends AnyStateReference {
  /// Wraps the given [parts] as a [StateReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  const StateReference(List<Object> parts): super(parts);

  /// Binds the state reference to a specific widget (identified by depth).
  ///
  /// Returns a [BoundStateReference] with the same [parts] and whose
  /// [BoundLoopReference.depth] is given by `depth`.
  BoundStateReference bind(int depth) {
    return BoundStateReference(depth, parts);
  }

  @override
  String toString() => 'state.${parts.join(".")}';
}

/// Bound reference to a remote widget's state.
///
/// This class is used to represent references of the form "state.foo.bar" after
/// the widgets have been constructed, so that the right state can be
/// identified.
///
/// This class is an internal detail of the RFW [Runtime] and is generally not
/// used directly.
class BoundStateReference extends AnyStateReference {
  /// Wraps the given [depth] and [parts] as a [BoundStateReference].
  ///
  /// The [parts] must not be mutated after the object is created.
  ///
  /// Generally this class is created using [StateReference.bind].
  const BoundStateReference(this.depth, List<Object> parts): super(parts);

  /// The widget to whose state the state reference refers.
  ///
  /// This identifies the widget by depth starting at the widget that was
  /// created by [Runtime.build] (or a [RemoteWidget], which uses that method).
  ///
  /// Since state references always go up the tree, this is an unambiguous way
  /// to reference state, even though in practice in the entire tree multiple
  /// widgets may be stateful at the same depth.
  final int depth;

  /// Creates a new [BoundStateRefererence] that indexes even deeper than this
  /// one (deeper into the specified widget's state, not into a deeper widget!).
  ///
  /// For example, suppose a widget's arguments consisted of a map with one key,
  /// "a", whose value was a [BoundStateRefererence] referencing "state.foo.bar".
  /// Now suppose that the widget itself has an [ArgsReference] that references
  /// "args.a.baz". The "args.a" part identifies the aforementioned
  /// [BoundStateReference], and so the resulting reference is actually to
  /// "state.foo.bar.baz".
  ///
  /// In this example, the [BoundStateReference] to "state.foo.bar" would have
  /// its [constructReference] method invoked by the runtime, with `["baz"]` as
  /// the `moreParts` argument, so that the resulting [BoundStateReference]'s
  /// [parts] is a combination of the original's (`["foo", "bar"]`) and the
  /// additional parts provided to the method.
  ///
  /// The [depth] is maintained in the new object.
  BoundStateReference constructReference(List<Object> moreParts) {
    return BoundStateReference(depth, parts + moreParts);
  }

  @override
  String toString() => 'state^$depth.${parts.join(".")}';
}

/// Base class for [EventHandler] and [SetStateHandler].
///
/// This is used by the [Runtime] to quickly filter out objects that are not
/// event handlers of any kind.
abstract class AnyEventHandler extends BlobNode {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const AnyEventHandler();
}

/// Description of a callback in an RFW widget declaration.
///
/// This represents a signal to send to the application using the RFW package.
/// Typically applications either handle such messages locally, or forward them
/// to a server for further processing.
class EventHandler extends AnyEventHandler {
  /// Wraps the given event name and arguments in an [EventHandler] object.
  ///
  /// The [eventArguments] must not be mutated after the object is created.
  const EventHandler(this.eventName, this.eventArguments);

  /// A string to identify the event. This provides an unambiguous identifier
  /// for the event, avoiding the need to establish a convention in the
  /// [eventArguments].
  final String eventName;

  /// The payload to provide with the event.
  final DynamicMap eventArguments;

  @override
  String toString() => 'event $eventName $eventArguments';
}

/// Description of a state setter in an RFW widget declaration.
///
/// This event handler is handled by the RFW [Runtime] itself by setting the
/// state referenced by [stateReference] to the value represented by [value]
/// when the event handler would be invoked.
class SetStateHandler extends AnyEventHandler {
  /// Wraps the given [stateReference] and [value] in a [SetStateHandler] object.
  ///
  /// The [value] must not be mutated after the object is created (e.g. in the
  /// event that it is a [DynamicMap] or [DynamicList]).
  const SetStateHandler(this.stateReference, this.value);

  /// Identifies the member in the widget's state to mutate.
  final AnyStateReference stateReference;

  /// The value to which the specified state will be set.
  final Object value;

  @override
  String toString() => 'set $stateReference = $value';
}

/// A library import.
///
/// Used to describe which libraries a remote widget libraries depends on. The
/// identified libraries can be local or remote. Import loops are invalid.
class Import extends BlobNode {
  /// Wraps the given library [name] in an [Import] object.
  const Import(this.name);

  /// The name of the library to import.
  final LibraryName name;

  @override
  String toString() => 'import $name;';
}

/// A description of a widget in a remote widget library.
///
/// The [root] must be either a [ConstructorCall] or a [Switch] that evaluates
/// to a [ConstructorCall]. (In principle one can imagine that an
/// [ArgsReference] that evaluates to a [ConstructorCall] would also be valid,
/// but such a construct would be redundant and would not provide any additional
/// expressivity, so it is disallowed.)
///
/// The tree rooted at [root] must not contain (directly or indirectly) a
/// [ConstructorCall] that references the widget declared by this
/// [WidgetDeclaration]: widget loops, even indirect loops or loops that would
/// in principle be terminated by use of a [Switch], are not allowed.
class WidgetDeclaration extends BlobNode {
  /// Binds the given [name] to the definition given by [root].
  ///
  /// The [initialState] may be null. If it is not, this represents a stateful widget.
  const WidgetDeclaration(this.name, this.initialState, this.root) : assert(root is ConstructorCall || root is Switch);

  /// The name of the widget that this declaration represents.
  ///
  /// This is the left hand side of a widget declaration.
  final String name;

  /// If non-null, this is a stateful widget; the value is used to create the
  /// initial copy of the state when the widget is created.
  final DynamicMap? initialState;

  /// The widget to return when this widget is used.
  ///
  /// This is usually a [ConstructorCall], but may be a [Switch] (so long as
  /// that [Switch] resolves to a [ConstructorCall]. Other values (or a [Switch]
  /// that does not resolve to a constructor call) will result in an
  /// [ErrorWidget] being used.
  final BlobNode root; // ConstructorCall or Switch

  @override
  String toString() => 'widget $name = $root;';
}

/// Base class for widget libraries.
abstract class WidgetLibrary {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const WidgetLibrary();
}

/// The in-memory representation of the output of [parseTextLibraryFile] or
/// [decodeLibraryBlob].
class RemoteWidgetLibrary extends WidgetLibrary {
  /// Wraps a set of [imports] and [widgets] (widget declarations) in a
  /// [RemoteWidgetLibrary] object.
  ///
  /// The provided lists must not be mutated once the library is created.
  const RemoteWidgetLibrary(this.imports, this.widgets);

  /// The list of libraries that this library depends on.
  ///
  /// This must not be empty, since at least one local widget library must be in
  /// scope in order for the remote widget library to be useful.
  final List<Import> imports;

  /// The list of widgets declared by this library.
  ///
  /// This can be empty.
  final List<WidgetDeclaration> widgets;

  @override
  String toString() => const Iterable<Object>.empty().followedBy(imports).followedBy(widgets).join('\n');
}
