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

import 'package:kernel/ast.dart';
import 'package:kernel/src/replacement_visitor.dart';

/// Returns `true` if type contains a promoted type variable.
bool hasPromotedTypeVariable(DartType type) {
  return type.accept(const _HasPromotedTypeVariableVisitor());
}

/// Visitor that returns `true` if a type contains a promoted type variable.
class _HasPromotedTypeVariableVisitor extends DartTypeVisitor<bool> {
  const _HasPromotedTypeVariableVisitor();

  @override
  bool defaultDartType(DartType node) => false;

  @override
  bool visitFunctionType(FunctionType node) {
    if (node.returnType.accept(this)) return true;
    for (DartType parameterType in node.positionalParameters) {
      if (parameterType.accept(this)) return true;
    }
    for (NamedType namedParameterType in node.namedParameters) {
      if (namedParameterType.type.accept(this)) return true;
    }
    return false;
  }

  @override
  bool visitInterfaceType(InterfaceType node) {
    for (DartType typeArgument in node.typeArguments) {
      if (typeArgument.accept(this)) return true;
    }
    return false;
  }

  @override
  bool visitTypedefType(TypedefType node) {
    for (DartType typeArgument in node.typeArguments) {
      if (typeArgument.accept(this)) return true;
    }
    return false;
  }

  @override
  bool visitTypeParameterType(TypeParameterType node) {
    return node.promotedBound != null;
  }
}

/// Returns [type] in which all promoted type variables have been replace with
/// their unpromoted equivalents, and where all nullabilities have been
/// normalized to the default nullability of [library].
///
/// If [library] is non-nullable by default all legacy types have been replaced
/// with non-nullable types. Otherwise all non-legacy types have been replaced
/// with legacy types.
DartType demoteTypeInLibrary(DartType type, Library library) {
  if (library.isNonNullableByDefault) {
    return type.accept1(
            const _DemotionNullabilityNormalization(
                demoteTypeVariables: true, forNonNullableByDefault: true),
            Variance.covariant) ??
        type;
  } else {
    return type.accept1(
            const _DemotionNullabilityNormalization(
                demoteTypeVariables: true, forNonNullableByDefault: false),
            Variance.covariant) ??
        type;
  }
}

/// Returns [type] normalized to the known nullabilities of [library].
///
/// If [library] is non-nullable by default [type] returned (non-nullable
/// libraries can handle all kinds of nullability). Otherwise all
/// non-legacy types have been replaced with legacy types (legacy libraries
/// can only handle legacy types).
DartType normalizeNullabilityInLibrary(DartType type, Library library) {
  if (library.isNonNullableByDefault) {
    return type;
  } else {
    return type.accept1(
            const _DemotionNullabilityNormalization(
                demoteTypeVariables: false, forNonNullableByDefault: false),
            Variance.covariant) ??
        type;
  }
}

/// Visitor that replaces all promoted type variables the type variable itself
/// and normalizes the type nullabilities.
///
/// The visitor returns `null` if the type wasn't changed.
class _DemotionNullabilityNormalization extends ReplacementVisitor {
  final bool demoteTypeVariables;
  final bool forNonNullableByDefault;

  const _DemotionNullabilityNormalization(
      {required this.demoteTypeVariables,
      required this.forNonNullableByDefault})
      // ignore: unnecessary_null_comparison
      : assert(demoteTypeVariables != null),
        // ignore: unnecessary_null_comparison
        assert(forNonNullableByDefault != null);

  @override
  Nullability? visitNullability(DartType node) {
    if (forNonNullableByDefault) {
      if (node.declaredNullability == Nullability.legacy) {
        return Nullability.nonNullable;
      }
    } else {
      if (node.declaredNullability != Nullability.legacy) {
        return Nullability.legacy;
      }
    }
    return null;
  }

  @override
  DartType? visitTypeParameterType(TypeParameterType node, int variance) {
    Nullability? newNullability = visitNullability(node);
    if (demoteTypeVariables && node.promotedBound != null) {
      return new TypeParameterType(
          node.parameter, newNullability ?? node.declaredNullability);
    }
    return createTypeParameterType(node, newNullability);
  }
}
