// Copyright (c) 2018, 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 'dart:math';

import 'package:kernel/ast.dart';

/// Class that holds the covariant and generic-covariant-impl information for
/// a member.
// TODO(johnniwinther): Cache this in ClassMember.
// TODO(johnniwinther): Maybe compact initial positional masks into a single
//  int.
class Covariance {
  static const int GenericCovariantImpl = 1;
  static const int Covariant = 2;

  /// Returns the covariance mask for [parameter].
  static int covarianceFromParameter(VariableDeclaration parameter) =>
      (parameter.isCovariant ? Covariant : 0) |
      (parameter.isGenericCovariantImpl ? GenericCovariantImpl : 0);

  /// Returns the covariance mask for [field].
  static int covarianceFromField(Field field) =>
      (field.isCovariant ? Covariant : 0) |
      (field.isGenericCovariantImpl ? GenericCovariantImpl : 0);

  /// Applies the [covariance] mask to [parameter].
  static void covarianceToParameter(
      int covariance, VariableDeclaration parameter) {
    if ((covariance & Covariant) != 0) {
      parameter.isCovariant = true;
    }
    if ((covariance & GenericCovariantImpl) != 0) {
      parameter.isGenericCovariantImpl = true;
    }
  }

  /// Applies the [covariance] mask to parameter.
  static void covarianceToField(int covariance, Field field) {
    if ((covariance & Covariant) != 0) {
      field.isCovariant = true;
    }
    if ((covariance & GenericCovariantImpl) != 0) {
      field.isGenericCovariantImpl = true;
    }
  }

  /// The covariance mask for the positional parameters.
  ///
  /// If no positional parameters have covariance, this is `null`.
  final List<int>? _positionalParameters;

  /// The covariance mask for the named parameters with name covariance.
  ///
  /// If no named parameters have covariance, this is `null`.
  final Map<String, int>? _namedParameters;

  /// The generic-covariant-impl state for the type parameters.
  ///
  /// If no type parameters are generic-covariant-impl, this is `null`.
  final List<bool>? _typeParameters;

  Covariance.internal(
      this._positionalParameters, this._namedParameters, this._typeParameters) {
    assert(_positionalParameters == null ||
        _positionalParameters!.any((element) => element != 0));
    assert(_namedParameters == null ||
        _namedParameters!.values.isNotEmpty &&
            _namedParameters!.values.every((element) => element != 0));
    assert(
        _typeParameters == null || _typeParameters!.any((element) => element));
  }

  /// The empty covariance.
  ///
  /// This is used for all members that do not use any covariance, regardless
  /// of parameter structure.
  const Covariance.empty()
      : _positionalParameters = null,
        _namedParameters = null,
        _typeParameters = null;

  /// Computes the covariance for the setter aspect of [field].
  ///
  /// The getter aspect of a field never uses covariance.
  factory Covariance.fromField(Field field) {
    int covariance = covarianceFromField(field);
    if (covariance == 0) {
      return const Covariance.empty();
    }
    return new Covariance.internal(<int>[covariance], null, null);
  }

  /// Computes the covariance for the [setter].
  factory Covariance.fromSetter(Procedure setter) {
    int covariance =
        covarianceFromParameter(setter.function!.positionalParameters.first);
    if (covariance == 0) {
      return const Covariance.empty();
    }
    return new Covariance.internal(<int>[covariance], null, null);
  }

  /// Computes the covariance for the [procedure].
  factory Covariance.fromMethod(Procedure procedure) {
    FunctionNode function = procedure.function!;
    List<int>? positionalParameters;
    if (function.positionalParameters.isNotEmpty) {
      for (int index = 0;
          index < function.positionalParameters.length;
          index++) {
        int covariance =
            covarianceFromParameter(function.positionalParameters[index]);
        if (covariance != 0) {
          positionalParameters ??=
              new List<int>.filled(function.positionalParameters.length, 0);
          positionalParameters[index] = covariance;
        }
      }
    }
    Map<String, int>? namedParameters;
    if (function.namedParameters.isNotEmpty) {
      for (int index = 0; index < function.namedParameters.length; index++) {
        VariableDeclaration parameter = function.namedParameters[index];
        int covariance = covarianceFromParameter(parameter);
        if (covariance != 0) {
          namedParameters ??= {};
          namedParameters[parameter.name!] = covariance;
        }
      }
    }
    List<bool>? typeParameters;
    if (function.typeParameters.isNotEmpty) {
      for (int index = 0; index < function.typeParameters.length; index++) {
        if (function.typeParameters[index].isGenericCovariantImpl) {
          typeParameters ??=
              new List<bool>.filled(function.typeParameters.length, false);
          typeParameters[index] = true;
        }
      }
    }
    if (positionalParameters == null &&
        namedParameters == null &&
        typeParameters == null) {
      return const Covariance.empty();
    }
    return new Covariance.internal(
        positionalParameters, namedParameters, typeParameters);
  }

  /// Computes the covariance for [member].
  ///
  /// If [forSetter] is `true`, the covariance is computed for the setter
  /// aspect of [member]. Otherwise, the covariance for the getter/method aspect
  /// of [member] is computed.
  factory Covariance.fromMember(Member member, {required bool forSetter}) {
    // ignore: unnecessary_null_comparison
    assert(forSetter != null);
    if (member is Procedure) {
      if (member.kind == ProcedureKind.Getter) {
        return const Covariance.empty();
      } else if (member.kind == ProcedureKind.Setter) {
        return new Covariance.fromSetter(member);
      } else {
        return new Covariance.fromMethod(member);
      }
    } else if (member is Field) {
      if (forSetter) {
        return new Covariance.fromField(member);
      } else {
        return const Covariance.empty();
      }
    } else {
      throw new UnsupportedError(
          "Unexpected member $member (${member.runtimeType})");
    }
  }

  /// Returns `true` if this is the empty covariance.
  bool get isEmpty =>
      _positionalParameters == null &&
      _namedParameters == null &&
      _typeParameters == null;

  /// Returns the covariance mask for the [index]th positional parameter.
  int getPositionalVariance(int index) {
    List<int>? positionalParameters = _positionalParameters;
    return positionalParameters != null && index < positionalParameters.length
        ? positionalParameters[index]
        : 0;
  }

  /// Returns the covariance mask for the named parameter with the [name].
  int getNamedVariance(String name) {
    Map<String, int>? namedParameters = _namedParameters;
    return namedParameters != null ? (namedParameters[name] ?? 0) : 0;
  }

  /// Returns `true` if the [index]th type parameter is generic-covariant-impl.
  bool isTypeParameterGenericCovariantImpl(int index) {
    List<bool>? typeParameters = _typeParameters;
    return typeParameters != null && index < typeParameters.length
        ? typeParameters[index]
        : false;
  }

  /// Returns the merge of this covariance with [other] in which parameters are
  /// covariant if they are covariant in either [this] or [other].
  Covariance merge(Covariance other) {
    if (identical(this, other)) return this;
    List<int>? positionalParameters;
    if (_positionalParameters == null) {
      positionalParameters = other._positionalParameters;
    } else if (other._positionalParameters == null) {
      positionalParameters = _positionalParameters;
    } else {
      positionalParameters = new List<int>.filled(
          max(_positionalParameters!.length,
              other._positionalParameters!.length),
          0);
      for (int index = 0; index < positionalParameters.length; index++) {
        positionalParameters[index] =
            getPositionalVariance(index) | other.getPositionalVariance(index);
      }
    }
    Map<String, int>? namedParameters;
    if (_namedParameters == null) {
      namedParameters = other._namedParameters;
    } else if (other._namedParameters == null) {
      namedParameters = _namedParameters;
    } else {
      namedParameters = {};
      Set<String> names = {
        ..._namedParameters!.keys,
        ...other._namedParameters!.keys
      };
      for (String name in names) {
        namedParameters[name] =
            getNamedVariance(name) | other.getNamedVariance(name);
      }
    }
    List<bool>? typeParameters;
    if (_typeParameters == null) {
      typeParameters = other._typeParameters;
    } else if (other._typeParameters == null) {
      typeParameters = _typeParameters;
    } else {
      typeParameters = new List<bool>.filled(
          max(_typeParameters!.length, other._typeParameters!.length), false);
      for (int index = 0; index < typeParameters.length; index++) {
        typeParameters[index] = isTypeParameterGenericCovariantImpl(index) ||
            other.isTypeParameterGenericCovariantImpl(index);
      }
    }
    if (positionalParameters == null &&
        namedParameters == null &&
        typeParameters == null) {
      return const Covariance.empty();
    }
    return new Covariance.internal(
        positionalParameters, namedParameters, typeParameters);
  }

  /// Update [member] to have the covariant flags set with the covariance in
  /// [this].
  ///
  /// No covariance bits are removed from [member] during this process.
  void applyCovariance(Member member) {
    if (isEmpty) return;
    if (member is Procedure) {
      FunctionNode function = member.function!;
      List<int>? positionalParameters = _positionalParameters;
      if (positionalParameters != null) {
        for (int index = 0; index < positionalParameters.length; index++) {
          if (index < function.positionalParameters.length) {
            covarianceToParameter(positionalParameters[index],
                function.positionalParameters[index]);
          }
        }
      }
      if (_namedParameters != null) {
        for (VariableDeclaration parameter in function.namedParameters) {
          covarianceToParameter(getNamedVariance(parameter.name!), parameter);
        }
      }
      List<bool>? typeParameters = _typeParameters;
      if (typeParameters != null) {
        for (int index = 0; index < typeParameters.length; index++) {
          if (index < function.typeParameters.length) {
            if (typeParameters[index]) {
              function.typeParameters[index].isGenericCovariantImpl = true;
            }
          }
        }
      }
    } else if (member is Field) {
      if (_positionalParameters != null) {
        covarianceToField(getPositionalVariance(0), member);
      }
    } else {
      throw new UnsupportedError(
          "Unexpected member $member (${member.runtimeType})");
    }
  }

  @override
  int get hashCode {
    int hash = 0;
    List<int>? positionalParameters = _positionalParameters;
    if (positionalParameters != null) {
      for (int covariance in positionalParameters) {
        hash += covariance.hashCode * 17;
      }
    }
    Map<String, int>? namedParameters = _namedParameters;
    if (namedParameters != null) {
      for (String name in namedParameters.keys) {
        hash += name.hashCode * 19 + namedParameters[name].hashCode * 23;
      }
    }
    List<bool>? typeParameters = _typeParameters;
    if (typeParameters != null) {
      for (bool covariance in typeParameters) {
        if (covariance) {
          hash += covariance.hashCode * 31;
        }
      }
    }
    return hash;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (other is Covariance) {
      if (_positionalParameters != other._positionalParameters) {
        if (_positionalParameters == null ||
            other._positionalParameters == null) {
          return false;
        }
        int positionalParameterCount = max(
            _positionalParameters!.length, other._positionalParameters!.length);
        for (int i = 0; i < positionalParameterCount; i++) {
          if (getPositionalVariance(i) != other.getPositionalVariance(i)) {
            return false;
          }
        }
      }
      if (_namedParameters != other._namedParameters) {
        if (_namedParameters == null || other._namedParameters == null) {
          return false;
        }
        Set<String> names = {
          ..._namedParameters!.keys,
          ...other._namedParameters!.keys
        };
        for (String name in names) {
          if (getNamedVariance(name) != other.getNamedVariance(name)) {
            return false;
          }
        }
      }
      if (_typeParameters != other._typeParameters) {
        if (_typeParameters == null || other._typeParameters == null) {
          return false;
        }
        int typeParameterCount =
            max(_typeParameters!.length, other._typeParameters!.length);
        for (int i = 0; i < typeParameterCount; i++) {
          if (isTypeParameterGenericCovariantImpl(i) !=
              other.isTypeParameterGenericCovariantImpl(i)) {
            return false;
          }
        }
      }
      return true;
    }
    return false;
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    if (isEmpty) {
      sb.write('Covariance.empty()');
    } else {
      sb.write('Covariance(');
      String comma = '';
      List<int>? positionalParameters = _positionalParameters;
      if (positionalParameters != null) {
        for (int index = 0; index < positionalParameters.length; index++) {
          if (positionalParameters[index] != 0) {
            sb.write(comma);
            sb.write('$index:');
            switch (positionalParameters[index]) {
              case GenericCovariantImpl:
                sb.write('GenericCovariantImpl');
                break;
              case Covariant:
                sb.write('Covariant');
                break;
              default:
                sb.write('GenericCovariantImpl+Covariant');
                break;
            }
            comma = ',';
          }
        }
      }
      Map<String, int>? namedParameters = _namedParameters;
      if (namedParameters != null) {
        for (String name in namedParameters.keys) {
          int covariance = namedParameters[name]!;
          if (covariance != 0) {
            sb.write(comma);
            sb.write('$name:');

            switch (covariance) {
              case GenericCovariantImpl:
                sb.write('GenericCovariantImpl');
                break;
              case Covariant:
                sb.write('Covariant');
                break;
              default:
                sb.write('GenericCovariantImpl+Covariant');
                break;
            }
            comma = ',';
          }
        }
      }
      List<bool>? typeParameters = _typeParameters;
      if (typeParameters != null) {
        sb.write(comma);
        sb.write('types:');
        comma = '';
        for (int index = 0; index < typeParameters.length; index++) {
          if (typeParameters[index]) {
            sb.write(comma);
            sb.write('$index');
            comma = ',';
          }
        }
      }
      sb.write(')');
    }
    return sb.toString();
  }
}
