// Copyright (c) 2022, 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 static com.android.tools.r8.utils.MapUtils.ignoreKey;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndMember;
import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.ir.analysis.type.DynamicType;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.optimize.membervaluepropagation.assume.AssumeInfo;
import com.android.tools.r8.utils.MapUtils;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

public class AssumeInfoCollection {

  private final Map<DexMember<?, ?>, AssumeInfo> backing;

  AssumeInfoCollection(Map<DexMember<?, ?>, AssumeInfo> backing) {
    assert backing.values().stream().noneMatch(AssumeInfo::isEmpty);
    this.backing = backing;
  }

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

  public boolean contains(DexClassAndMember<?, ?> member) {
    return backing.containsKey(member.getReference());
  }

  public AssumeInfo get(DexMember<?, ?> member) {
    return backing.getOrDefault(member, AssumeInfo.empty());
  }

  public AssumeInfo get(DexClassAndMember<?, ?> member) {
    return get(member.getReference());
  }

  public boolean isMaterializableInAllContexts(
      AppView<AppInfoWithLiveness> appView, DexClassAndMember<?, ?> member) {
    AbstractValue assumeValue = get(member).getAssumeValue();
    return assumeValue.isSingleValue()
        && assumeValue.asSingleValue().isMaterializableInAllContexts(appView);
  }

  public boolean isSideEffectFree(DexMember<?, ?> member) {
    return get(member).isSideEffectFree();
  }

  public boolean isSideEffectFree(DexClassAndMember<?, ?> member) {
    return isSideEffectFree(member.getReference());
  }

  public AssumeInfoCollection rewrittenWithLens(
      AppView<?> appView, GraphLens graphLens, GraphLens appliedLens) {
    Map<DexMember<?, ?>, AssumeInfo> rewrittenCollection = new IdentityHashMap<>();
    backing.forEach(
        (reference, info) -> {
          DexMember<?, ?> rewrittenReference =
              graphLens.getRenamedMemberSignature(reference, appliedLens);
          AssumeInfo rewrittenInfo = info.rewrittenWithLens(appView, graphLens);
          assert !rewrittenInfo.isEmpty();
          rewrittenCollection.put(rewrittenReference, rewrittenInfo);
        });
    return new AssumeInfoCollection(rewrittenCollection);
  }

  public AssumeInfoCollection withoutPrunedItems(PrunedItems prunedItems) {
    Map<DexMember<?, ?>, AssumeInfo> rewrittenCollection = new IdentityHashMap<>();
    backing.forEach(
        (reference, info) -> {
          if (!prunedItems.isRemoved(reference)) {
            AssumeInfo rewrittenInfo = info.withoutPrunedItems(prunedItems);
            if (!rewrittenInfo.isEmpty()) {
              rewrittenCollection.put(reference, rewrittenInfo);
            }
          }
        });
    return new AssumeInfoCollection(rewrittenCollection);
  }

  public static class Builder {

    private final Map<DexMember<?, ?>, AssumeInfo.Builder> backing = new ConcurrentHashMap<>();

    public Builder applyIf(boolean condition, Consumer<Builder> consumer) {
      if (condition) {
        consumer.accept(this);
      }
      return this;
    }

    public AssumeInfo buildInfo(DexClassAndMember<?, ?> member) {
      AssumeInfo.Builder builder = backing.get(member.getReference());
      return builder != null ? builder.build() : AssumeInfo.empty();
    }

    private AssumeInfo.Builder getOrCreateAssumeInfo(DexMember<?, ?> member) {
      return backing.computeIfAbsent(member, ignoreKey(AssumeInfo::builder));
    }

    private AssumeInfo.Builder getOrCreateAssumeInfo(DexClassAndMember<?, ?> member) {
      return getOrCreateAssumeInfo(member.getReference());
    }

    public boolean isEmpty() {
      return backing.isEmpty();
    }

    public Builder meet(DexMember<?, ?> member, AssumeInfo assumeInfo) {
      getOrCreateAssumeInfo(member).meet(assumeInfo);
      return this;
    }

    public Builder meetAssumeType(DexClassAndMember<?, ?> member, DynamicType assumeType) {
      getOrCreateAssumeInfo(member).meetAssumeType(assumeType);
      return this;
    }

    public Builder meetAssumeValue(DexMember<?, ?> member, AbstractValue assumeValue) {
      getOrCreateAssumeInfo(member).meetAssumeValue(assumeValue);
      return this;
    }

    public Builder meetAssumeValue(DexClassAndMember<?, ?> member, AbstractValue assumeValue) {
      return meetAssumeValue(member.getReference(), assumeValue);
    }

    public Builder setIsSideEffectFree(DexMember<?, ?> member) {
      getOrCreateAssumeInfo(member).setIsSideEffectFree();
      return this;
    }

    public Builder setIsSideEffectFree(DexClassAndMember<?, ?> member) {
      return setIsSideEffectFree(member.getReference());
    }

    public AssumeInfoCollection build() {
      return new AssumeInfoCollection(
          MapUtils.newIdentityHashMap(
              builder ->
                  backing.forEach(
                      (reference, infoBuilder) -> {
                        AssumeInfo info = infoBuilder.build();
                        if (!info.isEmpty()) {
                          builder.accept(reference, info);
                        }
                      }),
              backing.size()));
    }
  }
}
