// 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' hide MapEntry;
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>(a.typeArguments.length);
  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;
      }
    } else if (a == coreTypes.nullType &&
        b is NeverType &&
        b.nullability == Nullability.legacy) {
      // NNBD_TOP_MERGE(Null, Never*) = Null
      return coreTypes.nullType;
    }
    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 null;
  }

  @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 null;
  }

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