// Copyright (c) 2020, the R8 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.

package com.android.tools.r8.horizontalclassmerging.policies;

import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndField;
import com.android.tools.r8.graph.DexDefinition;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMember;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.horizontalclassmerging.HorizontalClassMerger.Mode;
import com.android.tools.r8.horizontalclassmerging.MergeGroup;
import com.android.tools.r8.horizontalclassmerging.MultiClassPolicy;
import com.android.tools.r8.shaking.VerticalClassMerger.IllegalAccessDetector;
import com.android.tools.r8.utils.TraversalContinuation;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

public class RespectPackageBoundaries extends MultiClassPolicy {

  private final AppView<? extends AppInfoWithClassHierarchy> appView;
  private final Mode mode;

  public RespectPackageBoundaries(AppView<? extends AppInfoWithClassHierarchy> appView, Mode mode) {
    this.appView = appView;
    this.mode = mode;
  }

  boolean shouldRestrictMergingAcrossPackageBoundary(DexProgramClass clazz) {
    // Check that the class is public, otherwise it is package private.
    if (!clazz.isPublic()) {
      return true;
    }

    // Annotations may access non-public items (or themselves be non-public), so for now we
    // conservatively restrict class merging when annotations are present.
    //
    // Note that in non-compat mode we should never see any annotations here, since we only merge
    // non-kept classes with non-kept members.
    if (clazz.hasAnnotations()
        || Iterables.any(clazz.members(), DexDefinition::hasAnyAnnotations)) {
      return true;
    }

    // Check that each implemented interface is public.
    for (DexType interfaceType : clazz.getInterfaces()) {
      if (clazz.getType().isSamePackage(interfaceType)) {
        DexClass interfaceClass = appView.definitionFor(interfaceType);
        if (interfaceClass == null || !interfaceClass.isPublic()) {
          return true;
        }
      }
    }

    // If any members are package private or protected, then their access depends on the package.
    for (DexEncodedMember<?, ?> member : clazz.members()) {
      if (member.getAccessFlags().isPackagePrivateOrProtected()) {
        return true;
      }
    }

    // If any field has a non-public type, then field merging may lead to check-cast instructions
    // being synthesized. These synthesized accesses depends on the package.
    for (DexEncodedField field : clazz.fields()) {
      DexType fieldBaseType = field.getType().toBaseType(appView.dexItemFactory());
      if (fieldBaseType.isClassType()) {
        DexClass fieldBaseClass = appView.definitionFor(fieldBaseType);
        if (fieldBaseClass == null || !fieldBaseClass.isPublic()) {
          return true;
        }
      }
    }

    // Check that all accesses from [clazz] to classes or members from the current package of
    // [clazz] will continue to work. This is guaranteed if the methods of [clazz] do not access
    // any private or protected classes or members from the current package of [clazz].
    TraversalContinuation<?, ?> result =
        clazz.traverseProgramMethods(
            method -> {
              boolean foundIllegalAccess =
                  method.registerCodeReferencesWithResult(
                      new IllegalAccessDetector(appView, method) {

                        @Override
                        protected boolean checkRewrittenFieldType(DexClassAndField field) {
                          if (mode.isInitial()) {
                            // If the type of the field is package private, we need to keep the
                            // current class in its package in case we end up synthesizing a
                            // check-cast for the field type after relaxing the type of the field
                            // after instance field merging.
                            DexType fieldBaseType = field.getType().toBaseType(dexItemFactory());
                            if (fieldBaseType.isClassType()) {
                              DexClass fieldBaseClass = appView.definitionFor(fieldBaseType);
                              if (fieldBaseClass == null || !fieldBaseClass.isPublic()) {
                                return setFoundPackagePrivateAccess();
                              }
                            }
                          } else {
                            // No relaxing of field types, hence no insertion of casts where we need
                            // to guarantee visibility.
                          }
                          return continueSearchForPackagePrivateAccess();
                        }
                      });
              if (foundIllegalAccess) {
                return TraversalContinuation.doBreak();
              }
              return TraversalContinuation.doContinue();
            });
    return result.shouldBreak();
  }

  /** Sort unrestricted classes into restricted classes if they are in the same package. */
  void tryFindRestrictedPackage(
      MergeGroup unrestrictedClasses, Map<String, MergeGroup> restrictedClasses) {
    unrestrictedClasses.removeIf(
        clazz -> {
          MergeGroup restrictedPackage = restrictedClasses.get(clazz.type.getPackageDescriptor());
          if (restrictedPackage != null) {
            restrictedPackage.add(clazz);
            return true;
          }
          return false;
        });
  }

  @Override
  public Collection<MergeGroup> apply(MergeGroup group) {
    Map<String, MergeGroup> restrictedClasses = new LinkedHashMap<>();
    MergeGroup unrestrictedClasses = new MergeGroup();

    // Sort all restricted classes into packages.
    for (DexProgramClass clazz : group) {
      if (shouldRestrictMergingAcrossPackageBoundary(clazz)) {
        restrictedClasses
            .computeIfAbsent(clazz.getType().getPackageDescriptor(), ignore -> new MergeGroup())
            .add(clazz);
      } else {
        unrestrictedClasses.add(clazz);
      }
    }

    tryFindRestrictedPackage(unrestrictedClasses, restrictedClasses);
    removeTrivialGroups(restrictedClasses.values());

    // TODO(b/166577694): Add the unrestricted classes to restricted groups, but ensure they aren't
    // the merge target.
    Collection<MergeGroup> groups = new ArrayList<>(restrictedClasses.size() + 1);
    if (unrestrictedClasses.size() > 1) {
      groups.add(unrestrictedClasses);
    }
    groups.addAll(restrictedClasses.values());
    return groups;
  }

  @Override
  public String getName() {
    return "RespectPackageBoundaries";
  }
}
