// 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.utils.codeinspector;

import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;

class CfTryCatchSubject implements TryCatchSubject {
  private final CodeInspector inspector;
  private final CfCode cfCode;
  private final CfTryCatch tryCatch;

  CfTryCatchSubject(CodeInspector inspector, CfCode cfCode, CfTryCatch tryCatch) {
    this.inspector = inspector;
    this.cfCode = cfCode;
    this.tryCatch = tryCatch;
  }

  @Override
  public RangeSubject getRange() {
    int index = 0;
    int startIndex = -1;
    int endIndex = -1;
    for (CfInstruction instruction : cfCode.instructions) {
      if (startIndex < 0 && instruction.equals(tryCatch.start)) {
        startIndex = index;
      }
      if (endIndex < 0 && instruction.equals(tryCatch.end)) {
        // To be inclusive, increase the index so that the range includes the current instruction.
        assertNotEquals(-1, startIndex);
        index++;
        endIndex = index;
        break;
      }
      index++;
    }
    assertNotEquals(-1, startIndex);
    assertNotEquals(-1, endIndex);
    assertTrue(startIndex < endIndex);
    return new RangeSubject(startIndex, endIndex);
  }

  @Override
  public boolean isCatching(String exceptionType) {
    for (DexType guardType : tryCatch.guards) {
      if (guardType.toString().equals(exceptionType)
        || guardType.toDescriptorString().equals(exceptionType)) {
        return true;
      }
    }
    return false;
  }

  @Override
  public boolean hasCatchAll() {
    return isCatching(DexItemFactory.throwableDescriptorString);
  }

  @Override
  public Stream<TypeSubject> streamGuards() {
    return tryCatch.guards.stream().map(type -> new TypeSubject(inspector, type));
  }

  @Override
  public Collection<TypeSubject> guards() {
    return streamGuards().collect(Collectors.toList());
  }

  @Override
  public int getNumberOfHandlers() {
    return tryCatch.guards.size();
  }
}
