// 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.GraphLens;
import com.android.tools.r8.graph.PrunedItems;
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 isSideEffectFree(DexMember<?, ?> member) {
    return get(member).isSideEffectFree();
  }

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

  public AssumeInfoCollection rewrittenWithLens(AppView<?> appView, GraphLens graphLens) {
    Map<DexMember<?, ?>, AssumeInfo> rewrittenCollection = new IdentityHashMap<>();
    backing.forEach(
        (reference, info) -> {
          DexMember<?, ?> rewrittenReference = graphLens.getRenamedMemberSignature(reference);
          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()));
    }
  }
}
