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

import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class PeepholeLayout {
  private List<List<Instruction>> instructions;
  private final PeepholeExpression[] expressions;
  private final boolean backwards;

  private PeepholeLayout(boolean backwards, PeepholeExpression... expressions) {
    this.instructions = new ArrayList<>(expressions.length);
    for (int i = 0; i < expressions.length; i++) {
      this.instructions.add(new ArrayList<>());
      expressions[i].setIndex(i);
    }
    this.backwards = backwards;
    this.expressions = expressions;
  }

  public static PeepholeLayout lookForward(PeepholeExpression... expressions) {
    return new PeepholeLayout(false, expressions);
  }

  public static PeepholeLayout lookBackward(PeepholeExpression... expressions) {
    return new PeepholeLayout(true, expressions);
  }

  public Match test(InstructionListIterator it) {
    if (backwards) {
      return testDirection(it::hasPrevious, it::previous, it::next);
    } else {
      return testDirection(it::hasNext, it::next, it::previous);
    }
  }

  private Match testDirection(
      Supplier<Boolean> hasNextInstruction,
      Supplier<Instruction> nextInstruction,
      Runnable resetOne) {
    if (!hasNextInstruction.get()) {
      return null;
    }
    boolean success = true;
    Instruction current = nextInstruction.get();
    int index;
    for (index = 0; index < expressions.length; index++) {
      PeepholeExpression e = expressions[index];
      List<Instruction> expInstructions = instructions.get(index);
      expInstructions.clear();
      if (current != null) {
        for (int i = 0; i < e.getMax(); i++) {
          if (!e.getPredicate().test(current)) {
            break;
          }
          expInstructions.add(current);
          if (!hasNextInstruction.get()) {
            current = null;
            break;
          }
          current = nextInstruction.get();
        }
      }
      success &= expInstructions.size() >= e.getMin() && expInstructions.size() <= e.getMax();
      if (!success) {
        break;
      }
    }
    for (int i = 0; i < index; i++) {
      for (int j = 0; j < instructions.get(i).size(); j++) {
        resetOne.run();
      }
    }
    if (current != null) {
      resetOne.run();
    }
    return success ? new Match(expressions, instructions) : null;
  }
}
