// Copyright (c) 2015, 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.

library dart2js.call_structure;

import '../common/names.dart' show Names;
import '../elements/entities.dart' show ParameterStructure;
import '../serialization/serialization.dart';
import '../util/util.dart';
import 'selector.dart' show Selector;

/// The structure of the arguments at a call-site.
///
/// A call-site passes some number of arguments: some positional arguments
/// followed by some named arguments. There may also be type arguments.
///
/// A CallStructure is unmodifiable.

// TODO(johnniwinther): Should isGetter/isSetter be part of the call structure
// instead of the selector?
class CallStructure {
  /// Tag used for identifying serialized [CallStructure] objects in a debugging
  /// data stream.
  static const String tag = 'call-structure';

  static const CallStructure NO_ARGS = CallStructure._(0);
  static const CallStructure ONE_ARG = CallStructure._(1);
  static const CallStructure TWO_ARGS = CallStructure._(2);

  static const List<List<CallStructure>> _common = [
    [NO_ARGS, CallStructure._(0, 1), CallStructure._(0, 2)],
    [ONE_ARG, CallStructure._(1, 1), CallStructure._(1, 2)],
    [TWO_ARGS, CallStructure._(2, 1), CallStructure._(2, 2)],
    [CallStructure._(3), CallStructure._(3, 1), CallStructure._(3, 2)],
    [CallStructure._(4), CallStructure._(4, 1), CallStructure._(4, 2)],
    [CallStructure._(5), CallStructure._(5, 1), CallStructure._(5, 2)],
    [CallStructure._(6)],
    [CallStructure._(7)],
    [CallStructure._(8)],
    [CallStructure._(9)],
    [CallStructure._(10)],
  ];

  /// The number of type arguments of the call.
  final int typeArgumentCount;

  /// The numbers of arguments of the call. Includes named arguments.
  final int argumentCount;

  /// The number of named arguments of the call.
  int get namedArgumentCount => 0;

  /// The number of positional argument of the call.
  int get positionalArgumentCount => argumentCount;

  const CallStructure._(this.argumentCount, [this.typeArgumentCount = 0]);

  factory CallStructure.unnamed(int argumentCount,
      [int typeArgumentCount = 0]) {
    // This simple canonicalization of common call structures greatly reduces
    // the number of allocations of CallStructure objects.
    if (argumentCount < _common.length) {
      final row = _common[argumentCount];
      if (typeArgumentCount < row.length) {
        final result = row[typeArgumentCount];
        assert(result.argumentCount == argumentCount &&
            result.typeArgumentCount == typeArgumentCount);
        return result;
      }
    }
    return CallStructure._(argumentCount, typeArgumentCount);
  }

  factory CallStructure(int argumentCount,
      [List<String>? namedArguments, int typeArgumentCount = 0]) {
    if (namedArguments == null || namedArguments.isEmpty) {
      return CallStructure.unnamed(argumentCount, typeArgumentCount);
    }
    return _NamedCallStructure(
        argumentCount, namedArguments, typeArgumentCount, null);
  }

  /// Deserializes a [CallStructure] object from [source].
  factory CallStructure.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    int argumentCount = source.readInt();
    List<String> namedArguments = source.readStrings()!;
    int typeArgumentCount = source.readInt();
    source.end(tag);
    return CallStructure(argumentCount, namedArguments, typeArgumentCount);
  }

  /// Serializes this [CallStructure] to [sink].
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeInt(argumentCount);
    sink.writeStrings(namedArguments);
    sink.writeInt(typeArgumentCount);
    sink.end(tag);
  }

  /// Returns `true` if this call structure is normalized, that is, its named
  /// arguments are sorted.
  bool get isNormalized => true;

  /// Returns the normalized version of this call structure.
  ///
  /// A [CallStructure] is normalized if its named arguments are sorted.
  CallStructure toNormalized() => this;

  CallStructure withTypeArgumentCount(int typeArgumentCount) =>
      CallStructure(argumentCount, namedArguments, typeArgumentCount);

  /// `true` if this call has named arguments.
  bool get isNamed => false;

  /// `true` if this call has no named arguments.
  bool get isUnnamed => true;

  /// The names of the named arguments in call-site order.
  List<String> get namedArguments => const [];

  /// The names of the named arguments in canonicalized order.
  List<String> getOrderedNamedArguments() => const [];

  CallStructure get nonGeneric => typeArgumentCount == 0
      ? this
      : CallStructure(argumentCount, namedArguments);

  /// Short textual representation use for testing.
  String get shortText {
    StringBuffer sb = StringBuffer();
    sb.write('(');
    sb.write(positionalArgumentCount);
    if (namedArgumentCount > 0) {
      sb.write(',');
      sb.write(getOrderedNamedArguments().join(','));
    }
    sb.write(')');
    return sb.toString();
  }

  /// A description of the argument structure.
  String structureToString() {
    StringBuffer sb = StringBuffer();
    sb.write('arity=$argumentCount');
    if (typeArgumentCount != 0) {
      sb.write(', types=$typeArgumentCount');
    }
    return sb.toString();
  }

  @override
  String toString() => 'CallStructure(${structureToString()})';

  Selector get callSelector => Selector.call(Names.call, this);

  bool match(CallStructure other) {
    if (identical(this, other)) return true;
    return this.argumentCount == other.argumentCount &&
        this.namedArgumentCount == other.namedArgumentCount &&
        this.typeArgumentCount == other.typeArgumentCount &&
        _sameNames(this.namedArguments, other.namedArguments);
  }

  // TODO(johnniwinther): Cache hash code?
  @override
  int get hashCode {
    return Hashing.listHash(
        namedArguments,
        Hashing.objectHash(argumentCount,
            Hashing.objectHash(typeArgumentCount, namedArguments.length)));
  }

  @override
  bool operator ==(other) {
    if (other is! CallStructure) return false;
    return match(other);
  }

  bool signatureApplies(ParameterStructure parameters) {
    int requiredParameterCount = parameters.requiredPositionalParameters;
    int optionalParameterCount = parameters.optionalParameters;
    int parameterCount = parameters.totalParameters;
    if (argumentCount > parameterCount) return false;
    if (positionalArgumentCount < requiredParameterCount) return false;
    if (typeArgumentCount != 0) {
      if (typeArgumentCount != parameters.typeParameters) return false;
    }

    if (parameters.namedParameters.isEmpty) {
      // We have already checked that the number of arguments are
      // not greater than the number of parameters. Therefore the
      // number of positional arguments are not greater than the
      // number of parameters.
      assert(positionalArgumentCount <= parameterCount);
      return namedArguments.isEmpty;
    } else {
      if (positionalArgumentCount > requiredParameterCount) return false;
      assert(positionalArgumentCount == requiredParameterCount);
      if (namedArgumentCount >
          optionalParameterCount + parameters.requiredNamedParameters.length)
        return false;

      int nameIndex = 0;
      List<String> namedParameters = parameters.namedParameters;
      int seenRequiredNamedParameters = 0;

      for (String name in getOrderedNamedArguments()) {
        bool found = false;
        // Note: we start at the existing index because arguments are sorted.
        while (nameIndex < namedParameters.length) {
          String parameterName = namedParameters[nameIndex];
          if (name == parameterName) {
            if (parameters.requiredNamedParameters.contains(name))
              seenRequiredNamedParameters++;
            found = true;
            break;
          }
          nameIndex++;
        }
        if (!found) return false;
      }
      return seenRequiredNamedParameters ==
          parameters.requiredNamedParameters.length;
    }
  }

  static bool _sameNames(List<String> first, List<String> second) {
    assert(first.length == second.length);
    for (int i = 0; i < first.length; i++) {
      if (first[i] != second[i]) return false;
    }
    return true;
  }
}

/// Call structure with named arguments. This is an implementation detail of the
/// CallStructure interface.
class _NamedCallStructure extends CallStructure {
  @override
  final List<String> namedArguments;

  /// The list of ordered named arguments is computed lazily. Initially `null`.
  List<String>? _orderedNamedArguments;

  _NamedCallStructure(int argumentCount, this.namedArguments,
      int typeArgumentCount, this._orderedNamedArguments)
      : assert(namedArguments.isNotEmpty),
        super._(argumentCount, typeArgumentCount);

  @override
  bool get isNamed => true;

  @override
  bool get isUnnamed => false;

  @override
  int get namedArgumentCount => namedArguments.length;

  @override
  int get positionalArgumentCount => argumentCount - namedArgumentCount;

  @override
  bool get isNormalized =>
      identical(namedArguments, getOrderedNamedArguments());

  @override
  CallStructure toNormalized() => isNormalized
      ? this
      : _NamedCallStructure(argumentCount, getOrderedNamedArguments(),
          typeArgumentCount, getOrderedNamedArguments());

  @override
  List<String> getOrderedNamedArguments() {
    return _orderedNamedArguments ??= _getOrderedNamedArguments();
  }

  List<String> _getOrderedNamedArguments() {
    List<String> ordered = List.of(namedArguments, growable: false);
    ordered.sort((String first, String second) => first.compareTo(second));
    // Use the same List if [namedArguments] is already ordered to indicate this
    // _NamedCallStructure is normalized.
    if (CallStructure._sameNames(ordered, namedArguments)) {
      return namedArguments;
    }
    return ordered;
  }

  @override
  String structureToString() {
    StringBuffer sb = StringBuffer();
    sb.write('arity=$argumentCount, named=[${namedArguments.join(', ')}]');
    if (typeArgumentCount != 0) {
      sb.write(', types=$typeArgumentCount');
    }
    return sb.toString();
  }
}
