// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.desugar;

import com.google.devtools.build.android.desugar.ClassSignatureParser.ClassSignature;
import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.Collections;
import java.util.LinkedHashSet;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;

/**
 * Visitor that renames emulated interfaces and marks classes that extend emulated interfaces to
 * also implement the renamed interfaces. {@link DefaultMethodClassFixer} makes sure the requisite
 * methods are present in all classes implementing the renamed interface. Doing this helps with
 * dynamic dispatch on emulated interfaces.
 */
public class EmulatedInterfaceRewriter extends ClassVisitor {

  private static final String[] EMPTY_ARRAY = new String[0];

  private final CoreLibrarySupport support;

  public EmulatedInterfaceRewriter(ClassVisitor dest, CoreLibrarySupport support) {
    super(Opcodes.ASM7, dest);
    this.support = support;
  }

  @Override
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    boolean emulated = support.isEmulatedCoreClassOrInterface(name);
    {
      // If signature is already broken (if it is null), we can't salvage it. Bail out.
      ClassSignature classSignature =
          signature != null
              ? ClassSignatureParser.readTypeParametersForInterfaces(
                  name, signature, superName, interfaces)
              : null;

      StringBuilder signatureAdditions = new StringBuilder();

      // 1. see if we should implement any additional interfaces.
      // Use LinkedHashSet to dedupe but maintain deterministic order
      LinkedHashSet<String> newInterfaces = new LinkedHashSet<>();
      if (interfaces != null && interfaces.length > 0) {
        // Make classes implementing emulated interfaces also implement the renamed interfaces we
        // create below.  This includes making the renamed interfaces extends each other as needed.
        Collections.addAll(newInterfaces, interfaces);
        for (int i = 0; i < interfaces.length; i++) {
          String itf = interfaces[i];

          if (support.isEmulatedCoreClassOrInterface(itf)) {
            String newInterface = support.renameCoreLibrary(itf);
            newInterfaces.add(newInterface);

            if (classSignature != null) {
              signatureAdditions
                  .append("L")
                  .append(newInterface)
                  .append(classSignature.interfaceTypeParameters().get(i))
                  .append(";");
            }
          }
        }
      }

      if (!emulated) {
        // For an immediate subclass of an emulated class, also fill in any interfaces implemented
        // by superclasses, similar to the additional default method stubbing performed in
        // DefaultMethodClassFixer in this situation.
        Class<?> superclass = support.getEmulatedCoreClassOrInterface(superName);
        while (superclass != null) {
          for (Class<?> implemented : superclass.getInterfaces()) {
            String itf = implemented.getName().replace('.', '/');
            if (support.isEmulatedCoreClassOrInterface(itf)) {
              String newInterface = support.renameCoreLibrary(itf);
              boolean added = newInterfaces.add(newInterface);

              // Make sure we don't generate the same signature for an interface implemented in
              // multiple superclasses
              if (classSignature != null && added) {
                signatureAdditions
                    .append("L")
                    .append(newInterface)
                    // TODO(b/137073683): Handle the case where superclass has additional type
                    // parameters not used in the emulated interface.
                    .append(classSignature.superClassSignature().typeParameters())
                    .append(";");
              }
            }
          }
          superclass = superclass.getSuperclass();
        }
      }
      // Update implemented interfaces and signature if we did anything above
      if (interfaces == null
          ? !newInterfaces.isEmpty()
          : interfaces.length != newInterfaces.size()) {
        interfaces = newInterfaces.toArray(EMPTY_ARRAY);
        if (signature != null) {
          // If we had no previous interfaces but have new interfaces from the super class, which
          // should still append this additions. Per the specification, it is valid to add these
          // interfaces after the superclass signature.
          signature += signatureAdditions;
        }
      }
    }

    // 2. see if we need to rename this interface itself
    if (BitFlags.isInterface(access) && emulated) {
      name = support.renameCoreLibrary(name);
    }
    super.visit(version, access, name, signature, superName, interfaces);
  }
}
