// Copyright (c) 2017, 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 '../ast.dart' hide MapEntry;
import '../type_algebra.dart';

/// Helper visitor that clones a type if a nested type is replaced, and
/// otherwise returns `null`.
class ReplacementVisitor implements DartTypeVisitor<DartType> {
  const ReplacementVisitor();

  void changeVariance() {}

  Nullability visitNullability(DartType node) => null;

  @override
  DartType visitFunctionType(FunctionType node) {
    Nullability newNullability = visitNullability(node);

    List<TypeParameter> newTypeParameters;
    for (int i = 0; i < node.typeParameters.length; i++) {
      TypeParameter typeParameter = node.typeParameters[i];
      DartType newBound = typeParameter.bound.accept(this);
      DartType newDefaultType = typeParameter.defaultType?.accept(this);
      if (newBound != null || newDefaultType != null) {
        newTypeParameters ??= node.typeParameters.toList(growable: false);
        newTypeParameters[i] = new TypeParameter(
            typeParameter.name,
            newBound ?? typeParameter.bound,
            newDefaultType ?? typeParameter.defaultType);
      }
    }

    Substitution substitution;
    if (newTypeParameters != null) {
      List<TypeParameterType> typeParameterTypes =
          new List<TypeParameterType>(newTypeParameters.length);
      for (int i = 0; i < newTypeParameters.length; i++) {
        typeParameterTypes[i] = new TypeParameterType.forAlphaRenaming(
            node.typeParameters[i], newTypeParameters[i]);
      }
      substitution =
          Substitution.fromPairs(node.typeParameters, typeParameterTypes);
      for (int i = 0; i < newTypeParameters.length; i++) {
        newTypeParameters[i].bound =
            substitution.substituteType(newTypeParameters[i].bound);
      }
    }

    DartType visitType(DartType type) {
      if (type == null) return null;
      DartType result = type.accept(this);
      if (substitution != null) {
        result = substitution.substituteType(result ?? type);
      }
      return result;
    }

    DartType newReturnType = visitType(node.returnType);
    changeVariance();
    List<DartType> newPositionalParameters = null;
    for (int i = 0; i < node.positionalParameters.length; i++) {
      DartType newType = visitType(node.positionalParameters[i]);
      if (newType != null) {
        newPositionalParameters ??=
            node.positionalParameters.toList(growable: false);
        newPositionalParameters[i] = newType;
      }
    }
    List<NamedType> newNamedParameters = null;
    for (int i = 0; i < node.namedParameters.length; i++) {
      DartType newType = visitType(node.namedParameters[i].type);
      NamedType newNamedType =
          createNamedType(node.namedParameters[i], newType);
      if (newNamedType != null) {
        newNamedParameters ??= node.namedParameters.toList(growable: false);
        newNamedParameters[i] = newNamedType;
      }
    }
    changeVariance();
    DartType newTypedefType = visitType(node.typedefType);

    return createFunctionType(
        node,
        newNullability,
        newTypeParameters,
        newReturnType,
        newPositionalParameters,
        newNamedParameters,
        newTypedefType);
  }

  NamedType createNamedType(NamedType node, DartType newType) {
    if (newType == null) {
      return null;
    } else {
      return new NamedType(node.name, newType, isRequired: node.isRequired);
    }
  }

  DartType createFunctionType(
      FunctionType node,
      Nullability newNullability,
      List<TypeParameter> newTypeParameters,
      DartType newReturnType,
      List<DartType> newPositionalParameters,
      List<NamedType> newNamedParameters,
      TypedefType newTypedefType) {
    if (newNullability == null &&
        newReturnType == null &&
        newPositionalParameters == null &&
        newNamedParameters == null &&
        newTypedefType == null) {
      // No nullability or types had to be substituted.
      return null;
    } else {
      return new FunctionType(
          newPositionalParameters ?? node.positionalParameters,
          newReturnType ?? node.returnType,
          newNullability ?? node.nullability,
          namedParameters: newNamedParameters ?? node.namedParameters,
          typeParameters: newTypeParameters ?? node.typeParameters,
          requiredParameterCount: node.requiredParameterCount,
          typedefType: newTypedefType ?? node.typedefType);
    }
  }

  @override
  DartType visitInterfaceType(InterfaceType node) {
    Nullability newNullability = visitNullability(node);
    List<DartType> newTypeArguments = null;
    for (int i = 0; i < node.typeArguments.length; i++) {
      DartType substitution = node.typeArguments[i].accept(this);
      if (substitution != null) {
        newTypeArguments ??= node.typeArguments.toList(growable: false);
        newTypeArguments[i] = substitution;
      }
    }
    return createInterfaceType(node, newNullability, newTypeArguments);
  }

  DartType createInterfaceType(InterfaceType node, Nullability newNullability,
      List<DartType> newTypeArguments) {
    if (newNullability == null && newTypeArguments == null) {
      // No nullability or type arguments needed to be substituted.
      return null;
    } else {
      if (node.classNode.name == 'Null' &&
          node.classNode.enclosingLibrary.importUri.scheme == 'dart' &&
          node.classNode.enclosingLibrary.importUri.path == 'core') {
        return null;
      }
      return new InterfaceType(
          node.classNode,
          newNullability ?? node.nullability,
          newTypeArguments ?? node.typeArguments);
    }
  }

  @override
  DartType visitFutureOrType(FutureOrType node) {
    Nullability newNullability = visitNullability(node);
    DartType newTypeArgument = node.typeArgument.accept(this);
    return createFutureOrType(node, newNullability, newTypeArgument);
  }

  DartType createFutureOrType(
      FutureOrType node, Nullability newNullability, DartType newTypeArgument) {
    if (newNullability == null && newTypeArgument == null) {
      // No nullability or type arguments needed to be substituted.
      return null;
    } else {
      return new FutureOrType(newTypeArgument ?? node.typeArgument,
          newNullability ?? node.declaredNullability);
    }
  }

  @override
  DartType visitDynamicType(DynamicType node) => null;

  @override
  DartType visitNeverType(NeverType node) {
    Nullability newNullability = visitNullability(node);
    return createNeverType(node, newNullability);
  }

  DartType createNeverType(NeverType node, Nullability newNullability) {
    if (newNullability == null) {
      // No nullability needed to be substituted.
      return null;
    } else {
      return new NeverType(newNullability);
    }
  }

  @override
  DartType visitInvalidType(InvalidType node) => null;

  @override
  DartType visitBottomType(BottomType node) => null;

  @override
  DartType visitVoidType(VoidType node) => null;

  @override
  DartType visitTypeParameterType(TypeParameterType node) {
    Nullability newNullability = visitNullability(node);
    if (node.promotedBound != null) {
      DartType newPromotedBound = node.promotedBound.accept(this);
      return createPromotedTypeParameterType(
          node, newNullability, newPromotedBound);
    }
    return createTypeParameterType(node, newNullability);
  }

  DartType createTypeParameterType(
      TypeParameterType node, Nullability newNullability) {
    if (newNullability == null) {
      // No nullability needed to be substituted.
      return null;
    } else {
      return new TypeParameterType(node.parameter, newNullability);
    }
  }

  DartType createPromotedTypeParameterType(TypeParameterType node,
      Nullability newNullability, DartType newPromotedBound) {
    if (newNullability == null && newPromotedBound == null) {
      // No nullability or bound needed to be substituted.
      return null;
    } else {
      return new TypeParameterType(
          node.parameter,
          newNullability ?? node.declaredNullability,
          newPromotedBound ?? node.promotedBound);
    }
  }

  @override
  DartType visitTypedefType(TypedefType node) {
    Nullability newNullability = visitNullability(node);
    List<DartType> newTypeArguments = null;
    for (int i = 0; i < node.typeArguments.length; i++) {
      DartType substitution = node.typeArguments[i].accept(this);
      if (substitution != null) {
        newTypeArguments ??= node.typeArguments.toList(growable: false);
        newTypeArguments[i] = substitution;
      }
    }
    return createTypedef(node, newNullability, newTypeArguments);
  }

  DartType createTypedef(TypedefType node, Nullability newNullability,
      List<DartType> newTypeArguments) {
    if (newNullability == null && newTypeArguments == null) {
      // No nullability or type arguments needed to be substituted.
      return null;
    } else {
      return new TypedefType(
          node.typedefNode,
          newNullability ?? node.nullability,
          newTypeArguments ?? node.typeArguments);
    }
  }

  @override
  DartType defaultDartType(DartType node) => null;
}
