// 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.shaking;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.synthesis.CommittedItems;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.Set;

public class MissingClasses {

  private final Set<DexType> missingClasses;

  private MissingClasses(Set<DexType> missingClasses) {
    this.missingClasses = missingClasses;
  }

  public Builder builder() {
    return new Builder(missingClasses);
  }

  public static Builder builderForInitialMissingClasses() {
    return new Builder();
  }

  public static MissingClasses empty() {
    return new MissingClasses(Sets.newIdentityHashSet());
  }

  public MissingClasses commitSyntheticItems(CommittedItems committedItems) {
    return builder()
        // TODO(b/175542052): Synthetic types should not be reported as missing in the first place.
        .removeAlreadyMissingClasses(committedItems.getLegacySyntheticTypes())
        .ignoreMissingClasses();
  }

  public boolean contains(DexType type) {
    return missingClasses.contains(type);
  }

  public static class Builder {

    private final Set<DexType> alreadyMissingClasses;
    private final Set<DexType> newMissingClasses = Sets.newIdentityHashSet();

    // Set of missing types that are not to be reported as missing. This does not hide reports
    // if the same type is in newMissingClasses in which case it is reported regardless.
    private final Set<DexType> newIgnoredMissingClasses = Sets.newIdentityHashSet();

    private Builder() {
      this(Sets.newIdentityHashSet());
    }

    private Builder(Set<DexType> alreadyMissingClasses) {
      this.alreadyMissingClasses = alreadyMissingClasses;
    }

    public void addNewMissingClass(DexType type) {
      newMissingClasses.add(type);
    }

    public Builder addNewMissingClasses(Collection<DexType> types) {
      newMissingClasses.addAll(types);
      return this;
    }

    public void ignoreNewMissingClass(DexType type) {
      newIgnoredMissingClasses.add(type);
    }

    public boolean contains(DexType type) {
      return alreadyMissingClasses.contains(type) || newMissingClasses.contains(type);
    }

    Builder removeAlreadyMissingClasses(Iterable<DexType> types) {
      for (DexType type : types) {
        alreadyMissingClasses.remove(type);
      }
      return this;
    }

    @Deprecated
    public MissingClasses ignoreMissingClasses() {
      return build();
    }

    public MissingClasses reportMissingClasses(InternalOptions options) {
      Set<DexType> newMissingClassesWithoutDontWarn =
          options.getProguardConfiguration().getDontWarnPatterns().getNonMatches(newMissingClasses);
      newMissingClassesWithoutDontWarn.removeAll(
          getAllowedMissingClasses(options.dexItemFactory()));
      if (!newMissingClassesWithoutDontWarn.isEmpty()) {
        MissingClassesDiagnostic diagnostic =
            new MissingClassesDiagnostic.Builder()
                .addMissingClasses(newMissingClassesWithoutDontWarn)
                .setFatal(!options.ignoreMissingClasses)
                .build();
        if (options.ignoreMissingClasses) {
          options.reporter.warning(diagnostic);
        } else {
          throw options.reporter.fatalError(diagnostic);
        }
      }
      return build();
    }

    private static Collection<DexType> getAllowedMissingClasses(DexItemFactory dexItemFactory) {
      return ImmutableList.of(dexItemFactory.annotationThrows);
    }

    /** Intentionally private, use {@link Builder#reportMissingClasses(InternalOptions)}. */
    private MissingClasses build() {
      // Extend the newMissingClasses set with all other missing classes.
      //
      // We also add newIgnoredMissingClasses to newMissingClasses to be able to assert that we have
      // a closed world after the first round of tree shaking: we should never lookup a class that
      // was not live or missing during the first round of tree shaking.
      // See also AppInfoWithLiveness.definitionFor().
      //
      // Note: At this point, all missing classes in newMissingClasses have already been reported.
      // Thus adding newIgnoredMissingClasses to newMissingClasses will not lead to reports for the
      // classes in newIgnoredMissingClasses.
      newMissingClasses.addAll(alreadyMissingClasses);
      newMissingClasses.addAll(newIgnoredMissingClasses);
      return new MissingClasses(newMissingClasses);
    }

    public boolean wasAlreadyMissing(DexType type) {
      return alreadyMissingClasses.contains(type);
    }
  }
}
