// 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 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': ");
    }
  }
}
