// Copyright (c) 2019, 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.ir.optimize.info.initializer;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.ConcreteMutableFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.EmptyFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.UnknownFieldSet;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfoCollection;
import com.android.tools.r8.shaking.AppInfoWithLiveness;

public final class NonTrivialInstanceInitializerInfo extends InstanceInitializerInfo {

  private static final int INSTANCE_FIELD_INITIALIZATION_INDEPENDENT_OF_ENVIRONMENT = 1 << 0;
  private static final int NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS = 1 << 1;
  private static final int RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN = 1 << 2;

  private final int data;
  private final InstanceFieldInitializationInfoCollection fieldInitializationInfos;
  private final AbstractFieldSet readSet;
  private final DexMethod parent;

  private NonTrivialInstanceInitializerInfo(
      int data,
      InstanceFieldInitializationInfoCollection fieldInitializationInfos,
      AbstractFieldSet readSet,
      DexMethod parent) {
    assert verifyNoUnknownBits(data);
    this.data = data;
    this.fieldInitializationInfos = fieldInitializationInfos;
    this.readSet = readSet;
    this.parent = parent;
  }

  private static boolean verifyNoUnknownBits(int data) {
    int knownBits =
        INSTANCE_FIELD_INITIALIZATION_INDEPENDENT_OF_ENVIRONMENT
            | NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS
            | RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN;
    assert (data & ~knownBits) == 0;
    return true;
  }

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

  @Override
  public DexMethod getParent() {
    return parent;
  }

  @Override
  public InstanceFieldInitializationInfoCollection fieldInitializationInfos() {
    return fieldInitializationInfos;
  }

  @Override
  public AbstractFieldSet readSet() {
    return readSet;
  }

  @Override
  public boolean instanceFieldInitializationMayDependOnEnvironment() {
    return (data & INSTANCE_FIELD_INITIALIZATION_INDEPENDENT_OF_ENVIRONMENT) == 0;
  }

  @Override
  public boolean mayHaveOtherSideEffectsThanInstanceFieldAssignments() {
    return (data & NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS) == 0;
  }

  @Override
  public boolean receiverNeverEscapesOutsideConstructorChain() {
    return (data & RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN) != 0;
  }

  @Override
  public NonTrivialInstanceInitializerInfo rewrittenWithLens(
      AppView<AppInfoWithLiveness> appView, GraphLens lens) {
    return new NonTrivialInstanceInitializerInfo(
        data,
        fieldInitializationInfos.rewrittenWithLens(appView, lens),
        readSet.rewrittenWithLens(appView, lens),
        lens.getRenamedMethodSignature(parent));
  }

  @Override
  public String toString() {
    return "NonTrivialInstanceInitializerInfo(" + fieldInitializationInfos + ")";
  }

  public static class Builder {

    private final InstanceFieldInitializationInfoCollection instanceFieldInitializationInfos;

    private int data =
        INSTANCE_FIELD_INITIALIZATION_INDEPENDENT_OF_ENVIRONMENT
            | NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS
            | RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN;
    private AbstractFieldSet readSet = EmptyFieldSet.getInstance();
    private DexMethod parent;

    public Builder(InstanceFieldInitializationInfoCollection instanceFieldInitializationInfos) {
      this.instanceFieldInitializationInfos = instanceFieldInitializationInfos;
    }

    private boolean isTrivial() {
      return instanceFieldInitializationInfos.isEmpty()
          && data == 0
          && readSet.isTop()
          && parent == null;
    }

    public Builder markFieldAsRead(DexEncodedField field) {
      if (readSet.isKnownFieldSet()) {
        if (readSet.isBottom()) {
          readSet = new ConcreteMutableFieldSet(field);
        } else {
          readSet.asConcreteFieldSet().add(field);
        }
      }
      assert readSet.contains(field);
      return this;
    }

    public Builder markFieldsAsRead(AbstractFieldSet otherReadSet) {
      if (readSet.isTop() || otherReadSet.isBottom()) {
        return this;
      }
      if (otherReadSet.isTop()) {
        return markAllFieldsAsRead();
      }
      ConcreteMutableFieldSet otherConcreteReadSet = otherReadSet.asConcreteFieldSet();
      if (readSet.isBottom()) {
        readSet = new ConcreteMutableFieldSet().addAll(otherConcreteReadSet);
      } else {
        readSet.asConcreteFieldSet().addAll(otherConcreteReadSet);
      }
      return this;
    }

    public Builder markAllFieldsAsRead() {
      readSet = UnknownFieldSet.getInstance();
      return this;
    }

    public Builder merge(InstanceInitializerInfo instanceInitializerInfo) {
      markFieldsAsRead(instanceInitializerInfo.readSet());
      if (instanceInitializerInfo.instanceFieldInitializationMayDependOnEnvironment()) {
        setInstanceFieldInitializationMayDependOnEnvironment();
      }
      if (instanceInitializerInfo.mayHaveOtherSideEffectsThanInstanceFieldAssignments()) {
        setMayHaveOtherSideEffectsThanInstanceFieldAssignments();
      }
      if (instanceInitializerInfo.receiverMayEscapeOutsideConstructorChain()) {
        setReceiverMayEscapeOutsideConstructorChain();
      }
      return this;
    }

    public Builder setInstanceFieldInitializationMayDependOnEnvironment() {
      data &= ~INSTANCE_FIELD_INITIALIZATION_INDEPENDENT_OF_ENVIRONMENT;
      return this;
    }

    public boolean mayHaveOtherSideEffectsThanInstanceFieldAssignments() {
      return (data & ~NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS) == 0;
    }

    public Builder setMayHaveOtherSideEffectsThanInstanceFieldAssignments() {
      data &= ~NO_OTHER_SIDE_EFFECTS_THAN_INSTANCE_FIELD_ASSIGNMENTS;
      return this;
    }

    public Builder setReceiverMayEscapeOutsideConstructorChain() {
      data &= ~RECEIVER_NEVER_ESCAPE_OUTSIDE_CONSTRUCTOR_CHAIN;
      return this;
    }

    public boolean hasParent() {
      return parent != null;
    }

    public DexMethod getParent() {
      return parent;
    }

    public Builder setParent(DexMethod parent) {
      assert !hasParent() || getParent() == parent;
      this.parent = parent;
      return this;
    }

    public InstanceInitializerInfo build() {
      return isTrivial()
          ? DefaultInstanceInitializerInfo.getInstance()
          : new NonTrivialInstanceInitializerInfo(
              data, instanceFieldInitializationInfos, readSet, parent);
    }
  }
}
