// Copyright (c) 2021, 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.graph;

import com.android.tools.r8.dex.CodeToKeep;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexCode.Try;
import com.android.tools.r8.graph.DexCode.TryHandler;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.utils.structural.CompareToVisitor;
import com.android.tools.r8.utils.structural.HashingVisitor;
import java.nio.ShortBuffer;

public interface DexWritableCode {

  enum DexWritableCodeKind {
    DEFAULT,
    DEFAULT_INSTANCE_INITIALIZER,
    THROW_NULL,
    THROW_EXCEPTION
  }

  boolean isThrowExceptionCode();

  ThrowExceptionCode asThrowExceptionCode();

  default int acceptCompareTo(DexWritableCode code, CompareToVisitor visitor) {
    DexWritableCodeKind kind = getDexWritableCodeKind();
    DexWritableCodeKind otherKind = code.getDexWritableCodeKind();
    if (kind != otherKind) {
      return kind.compareTo(otherKind);
    }
    switch (kind) {
      case DEFAULT:
        return asDexCode().acceptCompareTo(code.asDexCode(), visitor);
      case DEFAULT_INSTANCE_INITIALIZER:
        return 0;
      case THROW_NULL:
        return 0;
      case THROW_EXCEPTION:
        assert isThrowExceptionCode();
        return asThrowExceptionCode().acceptCompareTo(code.asThrowExceptionCode(), visitor);
      default:
        throw new Unreachable();
    }
  }

  void acceptHashing(HashingVisitor visitor);

  int codeSizeInBytes();

  void collectIndexedItems(
      AppView<?> appView,
      GraphLens codeLens,
      IndexedItemCollection indexedItems,
      ProgramMethod context,
      LensCodeRewriterUtils rewriter);

  void collectMixedSectionItems(MixedSectionCollection mixedItems);

  void writeKeepRulesForDesugaredLibrary(CodeToKeep codeToKeep);

  GraphLens getCodeLens(AppView<?> appView);

  DexDebugInfoForWriting getDebugInfoForWriting();

  DexWritableCodeKind getDexWritableCodeKind();

  DexString getHighestSortingString();

  TryHandler[] getHandlers();

  Try[] getTries();

  int getRegisterSize(ProgramMethod method);

  int getIncomingRegisterSize(ProgramMethod method);

  int getOutgoingRegisterSize();

  Code asCode();

  default boolean isDexCode() {
    return false;
  }

  default DexCode asDexCode() {
    return null;
  }

  DexWritableCacheKey getCacheLookupKey(ProgramMethod method, DexItemFactory factory);

  /** Rewrites the code to have JumboString bytecode if required by mapping. */
  DexWritableCode rewriteCodeWithJumboStrings(
      ProgramMethod method, ObjectToOffsetMapping mapping, AppView<?> appView, boolean force);

  void setCallSiteContexts(ProgramMethod method);

  void writeDex(
      ShortBuffer shortBuffer,
      ProgramMethod context,
      GraphLens graphLens,
      GraphLens codeLens,
      LensCodeRewriterUtils lensCodeRewriter,
      ObjectToOffsetMapping mapping);

  interface DexWritableCacheKey {}

  class DexWritableCodeKey implements DexWritableCacheKey {

    private final DexWritableCode code;
    private final int incomingRegisterSize;
    private final int registerSize;

    public DexWritableCodeKey(DexWritableCode code, int incomingRegisterSize, int registerSize) {
      this.code = code;
      this.incomingRegisterSize = incomingRegisterSize;
      this.registerSize = registerSize;
    }

    @Override
    public int hashCode() {
      return code.hashCode() + incomingRegisterSize * 13 + registerSize * 17;
    }

    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }
      if (!(other instanceof DexWritableCodeKey)) {
        return false;
      }
      DexWritableCodeKey that = (DexWritableCodeKey) other;
      return code.equals(that.code)
          && incomingRegisterSize == that.incomingRegisterSize
          && registerSize == that.registerSize;
    }
  }

  class AmendedDexWritableCodeKey<S> extends DexWritableCodeKey {
    private final S extra;

    public AmendedDexWritableCodeKey(
        DexWritableCode code, S extra, int incomingRegisterSize, int registerSize) {
      super(code, incomingRegisterSize, registerSize);
      this.extra = extra;
    }

    @Override
    public int hashCode() {
      return super.hashCode() + extra.hashCode() * 7;
    }

    @Override
    public boolean equals(Object other) {
      if (this == other) {
        return true;
      }
      if (!(other instanceof AmendedDexWritableCodeKey)) {
        return false;
      }
      AmendedDexWritableCodeKey that = (AmendedDexWritableCodeKey) other;
      return super.equals(other) && extra.equals(that.extra);
    }
  }
}
