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

import 'json_schema.dart';

String _toDartType(String type) {
  if (type.startsWith('#/definitions/')) {
    return type.replaceAll('#/definitions/', '');
  }
  switch (type) {
    case 'object':
      return 'Map<String, Object?>';
    case 'integer':
      return 'int';
    case 'number':
      return 'num';
    case 'string':
      return 'String';
    case 'boolean':
      return 'bool';
    case 'null':
      return 'Null';
    default:
      return type;
  }
}

String _toDartUnionType(List<String> types) {
  const allLiteralTypes = {
    'array',
    'boolean',
    'integer',
    'null',
    'number',
    'object',
    'string'
  };
  if (types.length == 7 && allLiteralTypes.containsAll(types)) {
    return 'Object';
  }
  return 'Either${types.length}<${types.map(_toDartType).join(', ')}>';
}

extension JsonSchemaExtensions on JsonSchema {
  JsonType typeFor(JsonType type) => type.dollarRef != null
      // TODO(dantup): Do we need to support more than just refs to definitions?
      ? definitions[type.refName]!
      : type;

  Map<String, JsonType> propertiesFor(JsonType type,
      {bool includeBase = true}) {
    // Merge this types direct properties with anything from the included
    // (allOf) types, but excluding those that come from the base class.
    final baseType = type.baseType;
    final includedBaseTypes =
        (type.allOf ?? []).where((t) => includeBase || t != baseType);
    final properties = {
      for (final other in includedBaseTypes) ...propertiesFor(typeFor(other)),
      ...?type.properties,
    };

    return properties;
  }
}

extension JsonTypeExtensions on JsonType {
  String asDartType({bool isOptional = false}) {
    final dartType = dollarRef != null
        ? _toDartType(dollarRef!)
        : oneOf != null
            ? _toDartUnionType(oneOf!.map((item) => item.asDartType()).toList())
            : type!.valueEquals('array')
                ? 'List<${items!.asDartType()}>'
                : type!.map(_toDartType, _toDartUnionType);

    return isOptional ? '$dartType?' : dartType;
  }

  /// Whether this type can have any type of value (Object/dynamic/any).
  bool get isAny => asDartType() == 'Object';

  /// Whether this type represents a List.
  bool get isList => type?.valueEquals('array') ?? false;

  /// Whether this type is a simple value that does not need any special handling.
  bool get isSimple {
    const _dartSimpleTypes = {
      'bool',
      'int',
      'num',
      'String',
      'Map<String, Object?>',
      'Null',
    };
    return _dartSimpleTypes.contains(asDartType());
  }

  /// Whether this type is a Union type using JSON schema's "oneOf" of where its
  /// [type] is a list of types.
  bool get isUnion =>
      oneOf != null || type != null && type!.map((_) => false, (_) => true);

  /// Whether this type is a reference to another spec type (using `dollarRef`).
  bool get isSpecType => dollarRef != null;

  /// Whether [propertyName] is a required for this type or its base types.
  bool requiresField(String propertyName) {
    if (required?.contains(propertyName) ?? false) {
      return true;
    }
    if (allOf?.any((type) => root.typeFor(type).requiresField(propertyName)) ??
        false) {
      return true;
    }

    return false;
  }

  /// The name of the type that this one references.
  String get refName => dollarRef!.replaceAll('#/definitions/', '');

  /// The literal value of this type, if it can have only one.
  ///
  /// These are represented in the spec using an enum with only a single value.
  String? get literalValue => enumValues?.singleOrNull;

  /// The base type for this type. Base types are inferred by a type using
  /// allOf and the first listed type being a reference (dollarRef) to another
  /// spec type.
  JsonType? get baseType {
    final all = allOf;
    if (all != null && all.length > 1 && all.first.dollarRef != null) {
      return all.first;
    }
    return null;
  }

  /// The list of possible types allowed by this union.
  ///
  /// May be represented using `oneOf` or a list of types in `type`.
  List<JsonType> get unionTypes {
    final types = oneOf ??
        // Fabricate a union for types where "type" is an array of literal types:
        // ['a', 'b']
        type!.map(
          (_) => throw 'unexpected non-union in isUnion condition',
          (types) =>
              types.map((t) => JsonType.fromJson(root, {'type': t})).toList(),
        )!;
    return types;
  }
}
