// 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;
    }
    TypedefType? typedefType = node.typedefType;
    if (typedefType != null && typedefType.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);
  }
}
