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

// @dart=2.12

import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart';
import 'package:kernel/type_algebra.dart';

/// Transforms the libraries in [libraries] by cloning any mixed in methods that
/// use super.
void transformLibraries(List<Library> libraries) {
  _CloneMixinMethodsWithSuper.transform(libraries);
}

class _CloneMixinMethodsWithSuper {
  /// Transform the given new [libraries].  It is expected that all other
  /// libraries have already been transformed.
  static void transform(List<Library> libraries) {
    // Clone any mixed in methods that uses super.
    var processedClasses = new Set<Class>();
    for (var library in libraries) {
      for (var cls in library.classes) {
        if (processedClasses.add(cls)) {
          transformClass(cls);
        }
      }
    }
  }

  /// Transforms a given class by cloning any mixed in methods that use super.
  static void transformClass(Class cls) {
    var mixedInClass = cls.mixedInClass;
    if (mixedInClass == null) return;
    var mixedInType = cls.mixedInType!;
    bool hasProcedureMaps = false;
    Map<Name, Procedure> existingNonSetters = {};
    Map<Name, Procedure> existingSetters = {};

    void ensureExistingProcedureMaps() {
      if (hasProcedureMaps) return;
      for (Procedure procedure in cls.procedures) {
        if (procedure.kind == ProcedureKind.Setter) {
          existingSetters[procedure.name] = procedure;
        } else {
          existingNonSetters[procedure.name] = procedure;
        }
      }
      hasProcedureMaps = true;
    }

    CloneVisitorWithMembers? cloneVisitor;
    for (var field in mixedInClass.mixin.fields) {
      if (field.containsSuperCalls) {
        cloneVisitor ??= MixinApplicationCloner(cls,
            typeSubstitution: getSubstitutionMap(mixedInType));
        // TODO(jensj): Provide a "referenceFrom" if we need to support
        // the incremental compiler.
        ensureExistingProcedureMaps();
        Procedure? existingGetter = existingNonSetters[field.name];
        Procedure? existingSetter = existingSetters[field.name];
        cls.addField(cloneVisitor.cloneField(
            field, existingGetter?.reference, existingSetter?.reference));
        if (existingGetter != null) {
          cls.procedures.remove(existingGetter);
        }
        if (existingSetter != null) {
          cls.procedures.remove(existingSetter);
        }
        continue;
      }
    }
    for (var procedure in mixedInClass.mixin.procedures) {
      if (procedure.containsSuperCalls) {
        cloneVisitor ??= MixinApplicationCloner(cls,
            typeSubstitution: getSubstitutionMap(mixedInType));
        // TODO(jensj): Provide a "referenceFrom" if we need to support
        // the incremental compiler.
        ensureExistingProcedureMaps();
        Procedure? existingProcedure = procedure.kind == ProcedureKind.Setter
            ? existingSetters[procedure.name]
            : existingNonSetters[procedure.name];
        if (existingProcedure != null) {
          cls.procedures.remove(existingProcedure);
        }
        cls.addProcedure(cloneVisitor.cloneProcedure(
            procedure, existingProcedure?.reference));
        continue;
      }
    }
  }
}
