// 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 '../ast.dart';
import '../core_types.dart';

import 'merge_visitor.dart';

/// Returns the NNBD_TOP_MERGE of [a] and [b]. If [a] and [b] have no defined
/// NNBD_TOP_MERGE `null` is returned.
Supertype? nnbdTopMergeSupertype(
    CoreTypes coreTypes, Supertype a, Supertype b) {
  assert(a.classNode == b.classNode);
  if (a.typeArguments.isEmpty) {
    return a;
  }
  List<DartType> newTypeArguments =
      new List<DartType>.filled(a.typeArguments.length, dummyDartType);
  for (int i = 0; i < a.typeArguments.length; i++) {
    DartType? newTypeArgument =
        nnbdTopMerge(coreTypes, a.typeArguments[i], b.typeArguments[i]);
    if (newTypeArgument == null) return null;
    newTypeArguments[i] = newTypeArgument;
  }
  return new Supertype(a.classNode, newTypeArguments);
}

/// Returns the NNBD_TOP_MERGE of [a] and [b]. If [a] and [b] have no defined
/// NNBD_TOP_MERGE `null` is returned.
DartType? nnbdTopMerge(CoreTypes coreTypes, DartType a, DartType b) {
  if (a == b) return a;
  return a.accept1(new NnbdTopMergeVisitor(coreTypes), b);
}

class NnbdTopMergeVisitor extends MergeVisitor {
  final CoreTypes coreTypes;

  NnbdTopMergeVisitor(this.coreTypes);

  @override
  Nullability? mergeNullability(Nullability a, Nullability b) {
    if (a == b) {
      return a;
    } else if (a == Nullability.legacy) {
      return b;
    } else if (b == Nullability.legacy) {
      return a;
    }
    return null;
  }

  @override
  DartType? visitInterfaceType(InterfaceType a, DartType b) {
    if (a == coreTypes.objectNullableRawType) {
      if (b is DynamicType) {
        // NNBD_TOP_MERGE(Object?, dynamic) = Object?
        return coreTypes.objectNullableRawType;
      } else if (b is VoidType) {
        // NNBD_TOP_MERGE(Object?, void) = Object?
        return coreTypes.objectNullableRawType;
      } else if (b == coreTypes.objectNullableRawType) {
        // NNBD_TOP_MERGE(Object?, Object?) = Object?
        return coreTypes.objectNullableRawType;
      }
    } else if (a == coreTypes.objectLegacyRawType) {
      if (b is DynamicType) {
        // NNBD_TOP_MERGE(Object*, dynamic) = Object?
        return coreTypes.objectNullableRawType;
      } else if (b is VoidType) {
        // NNBD_TOP_MERGE(Object*, void) = Object?
        return coreTypes.objectNullableRawType;
      }
    }
    return super.visitInterfaceType(a, b);
  }

  @override
  DartType? visitVoidType(VoidType a, DartType b) {
    if (b is DynamicType) {
      // NNBD_TOP_MERGE(void, dynamic) = Object?
      return coreTypes.objectNullableRawType;
    } else if (b is VoidType) {
      // NNBD_TOP_MERGE(void, void) = void
      return const VoidType();
    } else if (b == coreTypes.objectNullableRawType) {
      // NNBD_TOP_MERGE(void, Object?) = Object?
      return coreTypes.objectNullableRawType;
    } else if (b == coreTypes.objectLegacyRawType) {
      // NNBD_TOP_MERGE(void, Object*) = Object?
      return coreTypes.objectNullableRawType;
    }
    return super.visitVoidType(a, b);
  }

  @override
  DartType? visitDynamicType(DynamicType a, DartType b) {
    if (b is DynamicType) {
      // NNBD_TOP_MERGE(dynamic, dynamic) = dynamic
      return const DynamicType();
    } else if (b is VoidType) {
      // NNBD_TOP_MERGE(dynamic, void) = Object?
      return coreTypes.objectNullableRawType;
    } else if (b == coreTypes.objectNullableRawType) {
      // NNBD_TOP_MERGE(dynamic, Object?) = Object?
      return coreTypes.objectNullableRawType;
    } else if (b == coreTypes.objectLegacyRawType) {
      // NNBD_TOP_MERGE(dynamic, Object*) = Object?
      return coreTypes.objectNullableRawType;
    }
    return super.visitDynamicType(a, b);
  }

  @override
  DartType? visitNeverType(NeverType a, DartType b) {
    if (a.nullability == Nullability.legacy && b is NullType) {
      // NNBD_TOP_MERGE(Never*, Null) = Null
      return const NullType();
    }
    return super.visitNeverType(a, b);
  }

  @override
  DartType? visitNullType(NullType a, DartType b) {
    if (b is NeverType && b.nullability == Nullability.legacy) {
      // NNBD_TOP_MERGE(Null, Never*) = Null
      return const NullType();
    }
    return super.visitNullType(a, b);
  }
}
