// 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.retrace.api;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.retrace.ProguardMapProducer;
import com.android.tools.r8.retrace.RetraceFrameElement;
import com.android.tools.r8.retrace.RetraceStackTraceContext;
import com.android.tools.r8.retrace.RetracedMethodReference;
import com.android.tools.r8.retrace.RetracedSingleFrame;
import com.android.tools.r8.retrace.Retracer;
import java.util.List;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class RetraceApiOutlineInOutlineStackTrace extends RetraceApiTestBase {

  public RetraceApiOutlineInOutlineStackTrace(TestParameters parameters) {
    super(parameters);
  }

  @Override
  protected Class<? extends RetraceApiBinaryTest> binaryTestClass() {
    return ApiTest.class;
  }

  public static class ApiTest implements RetraceApiBinaryTest {

    private final ClassReference outline1Renamed = Reference.classFromTypeName("a");
    private final ClassReference outline2Renamed = Reference.classFromTypeName("b");
    private final ClassReference callsiteOriginal = Reference.classFromTypeName("some.Class");
    private final ClassReference callsiteRenamed = Reference.classFromTypeName("c");

    private final String mapping =
        "# { id: 'com.android.tools.r8.mapping', version: '2.0' }\n"
            + "outline1.Class -> "
            + outline1Renamed.getTypeName()
            + ":\n"
            + "  3:4:int outline():0:0 -> a\n"
            + "# { 'id':'com.android.tools.r8.outline' }\n"
            + "outline2.Class -> "
            + outline2Renamed.getTypeName()
            + ":\n"
            + "  6:6:int outline():0:0 -> a\n"
            + "# { 'id':'com.android.tools.r8.outlineCallsite', "
            + "     'positions': { '3': 42, '4': 43 } }\n"
            + "  42:43:int outline():0:0 -> a\n" // This is another call to the outline
            + "# { 'id':'com.android.tools.r8.outline' }\n"
            + callsiteOriginal.getTypeName()
            + " -> "
            + callsiteRenamed.getTypeName()
            + ":\n"
            + "  1:1:void foo.bar.Baz.qux():42:42 -> s\n"
            + "  10:11:int foo.bar.baz.outlineCaller(int):98:99 -> s\n"
            + "  28:28:int outlineCaller(int):0:0 -> s\n" // This is the actual call to the outline
            + "# { 'id':'com.android.tools.r8.outlineCallsite', "
            + "     'positions': { '42': 10, '43': 11 } }\n";

    @Test
    public void test() {
      Retracer retracer =
          Retracer.createExperimental(
              ProguardMapProducer.fromString(mapping), new DiagnosticsHandler() {});
      // Retrace the first outline.
      RetraceStackTraceContext outlineContext =
          retraceOutline(
              retracer,
              Reference.methodFromDescriptor(outline1Renamed, "a", "()I"),
              4,
              RetraceStackTraceContext.empty());

      // Retrace the second outline using the context of the first retracing.
      outlineContext =
          retraceOutline(
              retracer,
              Reference.methodFromDescriptor(outline2Renamed, "a", "()I"),
              6,
              outlineContext);

      List<RetraceFrameElement> retraceOutlineCallee =
          retracer
              .retraceFrame(
                  outlineContext,
                  OptionalInt.of(28),
                  Reference.methodFromDescriptor(callsiteRenamed, "s", "(I)V"))
              .stream()
              .collect(Collectors.toList());
      assertEquals(1, retraceOutlineCallee.size());

      List<RetracedMethodReference> outlineCallSiteFrames =
          retraceOutlineCallee.get(0).stream()
              .map(RetracedSingleFrame::getMethodReference)
              .collect(Collectors.toList());
      assertEquals(1, outlineCallSiteFrames.size());
      assertEquals(99, outlineCallSiteFrames.get(0).getOriginalPositionOrDefault(28));
    }

    private RetraceStackTraceContext retraceOutline(
        Retracer retracer,
        MethodReference reference,
        int position,
        RetraceStackTraceContext context) {
      List<RetraceFrameElement> outlineRetraced =
          retracer.retraceFrame(context, OptionalInt.of(position), reference).stream()
              .collect(Collectors.toList());
      // The retrace result should not be ambiguous or empty.
      assertEquals(1, outlineRetraced.size());
      RetraceFrameElement retraceFrameElement = outlineRetraced.get(0);

      // Check that visiting all frames report the outline.
      List<RetracedMethodReference> allMethodReferences =
          retraceFrameElement.stream()
              .map(RetracedSingleFrame::getMethodReference)
              .collect(Collectors.toList());
      assertEquals(1, allMethodReferences.size());
      assertEquals(0, allMethodReferences.get(0).getOriginalPositionOrDefault(position));

      // Check that visiting rewritten frames will not report anything.
      List<RetracedMethodReference> rewrittenReferences =
          retraceFrameElement
              .streamRewritten(RetraceStackTraceContext.empty())
              .map(RetracedSingleFrame::getMethodReference)
              .collect(Collectors.toList());
      assertEquals(0, rewrittenReferences.size());

      return retraceFrameElement.getRetraceStackTraceContext();
    }
  }
}
