// Copyright (c) 2022, 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.md file.

/// A value of type [T] read from a yaml/json-like structure.
abstract class Value<T> {
  const Value();

  /// Reads the [T] value from [value].
  ///
  /// If the [value] isn't a valid encoding of [T] an [ArgumentError] is thrown
  /// using [context] to provide additional information in the error message.
  T read(dynamic value, {String context = ''});
}

/// A `bool` value encoded as a bool.
class BoolValue extends Value<bool> {
  const BoolValue();

  @override
  bool read(dynamic value, {String context = ''}) {
    if (value is bool) {
      return value;
    } else {
      throw new ArgumentError("${context}Value must be a boolean.");
    }
  }
}

/// A `String` value encoded as a string.
///
/// If [options] is provided, only values in [options] are allowed.
class StringValue extends Value<String> {
  final Set<String>? options;

  const StringValue({this.options});

  @override
  String read(dynamic value, {String context = ''}) {
    if (value is String) {
      if (options != null && !options!.contains(value)) {
        throw new ArgumentError("${context}Unexpected value '${value}'. "
            "Expected one of: ${options!.join(',')}.");
      }
      return value;
    } else {
      throw new ArgumentError("${context}Value must be a string.");
    }
  }
}

/// An `int` value encoded as an integer.
class IntValue extends Value<int> {
  const IntValue();

  @override
  int read(dynamic value, {String context = ''}) {
    if (value is int) {
      return value;
    } else {
      throw new ArgumentError("${context}Value must be a integer.");
    }
  }
}

/// A `List<E>` value encoded as a list or a single element, if
/// [supportSingleton] is `true`.
///
/// The individual elements of type [E] are read using the [elementReader].
class ListValue<E> extends Value<List<E>> {
  final Value<E> elementReader;
  final bool supportSingleton;

  const ListValue(this.elementReader, {this.supportSingleton: false});

  @override
  List<E> read(dynamic value, {String context = ''}) {
    if (value is List) {
      List<E> list = [];
      for (dynamic element in value) {
        list.add(elementReader.read(element));
      }
      return list;
    } else if (supportSingleton) {
      return [elementReader.read(value, context: context)];
    } else {
      throw new ArgumentError("${context}Value must be a list.");
    }
  }
}

/// A `Map<String, V>` value encoded as a map.
///
/// The individual map entry values of type [V] are read using the
/// [valueReader].
class MapValue<V> extends Value<Map<String, V>> {
  final Value<V> valueReader;

  const MapValue(this.valueReader);

  @override
  Map<String, V> read(dynamic value, {String context = ''}) {
    if (value is Map) {
      Map<String, V> map = {};
      value.forEach((key, value) {
        map[key as String] = valueReader.read(value, context: context);
      });
      return map;
    } else {
      throw new ArgumentError("${context}Value must be a map.");
    }
  }
}

/// An enum value of type [E] encoding as a string using the enum value name.
class EnumValue<E extends Enum> extends Value<E> {
  final List<E> enumValues;

  const EnumValue(this.enumValues);

  @override
  E read(dynamic value, {String context = ''}) {
    if (value is String) {
      for (E enumValue in enumValues) {
        if (value == enumValue.name) {
          return enumValue;
        }
      }
      throw new ArgumentError("${context}Unexpected value: '${value}'. "
          "Expected one of: ${enumValues.map((e) => e.name).join(',')}.");
    } else {
      throw new ArgumentError("${context}Value must be a string.");
    }
  }
}

/// A value of type [O] encoded as a value of type [I], using [valueReader] to
/// decode the value.
class CustomValue<I, O> extends Value<O> {
  final O Function(I) valueReader;

  const CustomValue(this.valueReader);

  @override
  O read(dynamic value, {String context = ''}) {
    if (value is I) {
      return valueReader(value);
    } else {
      throw new ArgumentError("${context}Value must be of type $I.");
    }
  }
}

/// A potentially optional named property of type [T].
///
/// This class can be used to document and support the decoding of properties
/// defined in a yaml/json-like map.
class Property<T> {
  /// The name of the property as found in property map.
  final String name;

  /// The reader used to decode values of this property.
  final Value<T> valueReader;

  /// The default value for this property if omitted.
  final T? defaultValue;

  /// Whether this property is required.
  final bool required;

  /// Creates a required property with given [name] that uses [valueReader] to
  /// decode its value.
  const Property.required(this.name, this.valueReader)
      : required = true,
        defaultValue = null,
        assert(null is! T);

  /// Creates an optional property with given [name] that uses [valueReader] to
  /// decode its value when present and [defaultValue] if omitted.
  const Property.optional(this.name, this.valueReader, {this.defaultValue})
      : required = false,
        assert(defaultValue is T);

  /// Reads this property from [map].
  ///
  /// If [keys] is provided, [name] is removed from [keys] to signal that this
  /// property has been recognized. This can be used to detect and report
  /// unknown/unsupported properties.
  T read(Map map, [Set<String>? keys]) {
    dynamic value = map[name];
    keys?.remove(name);
    if (value == null) {
      if (required) {
        throw new ArgumentError("Missing property '$name'.");
      }
      return defaultValue as T;
    } else {
      return valueReader.read(value, context: "Property '$name': ");
    }
  }
}
