/*
 * Copyright (C) 2016 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.copybara.profiler;


import com.google.common.base.Throwables;
import com.google.common.flogger.FluentLogger;
import java.time.Duration;
import java.util.List;

/**
 * A simple callback for the profiler that logs the execution of the tasks when they finish.
 */
public class LogProfilerListener implements Listener {

  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  @Override
  public void taskStarted(Task task) {
    // Ignored. We only record the finish event
  }

  @Override
  public void taskFinished(Task task) {
    List<StackTraceElement> stack = Throwables.lazyStackTrace(new Throwable());
    if (stack != null && stack.size() > 2) {
      // Call-site -> profiler -> this
      int depth = 2;
      StackTraceElement caller = stack.get(depth);
      // Depending on the JVM, we might have added entries
      while ((caller.getClassName().equals("com.google.copybara.profiler.Profiler") 
          || caller.getMethodName().startsWith("$")) 
          && stack.size() > depth + 1) {
        depth++;
        caller = stack.get(depth);
      }
      logger.atInfo()
          .withInjectedLogSite(
              caller.getClassName(),
              caller.getMethodName(),
              caller.getLineNumber(),
              caller.getFileName())
          .log("PROFILE: %6d %s",
              Duration.ofNanos(task.elapsedNanos()).toMillis(), task.getDescription());
      return;
    }
    logger.atInfo().log("PROFILE: %6d %s",
        Duration.ofNanos(task.elapsedNanos()).toMillis(), task.getDescription());
  }
}

@@ -632,51 +632,8 @@
 r;%0A%0A
-%0Aimport com.google.common.base.Throwables;%0A
 impo
@@ -705,31 +705,8 @@
 ion;
-%0Aimport java.util.List;
 %0A%0A/*
@@ -1104,319 +1104,221 @@
     
-List%3CStackTraceElement%3E stack = Throwables.lazyStackTrace(new Throwable());%0A    if (stack != null && stack.size() %3E 2) %7B%0A      // Call-site -%3E profiler -%3E this%0A      int depth = 2;%0A      StackTraceElement caller = stack.get(depth);%0A      // Depending on the JVM, we might have added entries%0A      while ((caller
+StackWalker.getInstance()%0A        .walk(%0A            stream -%3E%0A                stream%0A                    .skip(2)%0A                    .dropWhile(%0A                        frame -%3E%0A                            frame
 .get
@@ -1376,18 +1376,39 @@
 ofiler%22)
- 
 %0A
+                      
         
@@ -1412,22 +1412,21 @@
      %7C%7C 
-caller
+frame
 .getMeth
@@ -1454,10 +1454,15 @@
 $%22))
- 
 %0A
+      
     
@@ -1471,64 +1471,61 @@
     
-&& stack.size() %3E depth + 1) %7B%0A        depth++;%0A
+    .findFirst())%0A        .ifPresentOrElse(%0A 
         
 call
@@ -1524,43 +1524,31 @@
     
+   
 caller 
-= stack.get(depth);%0A
+-%3E%0A    
       
-%7D%0A
     
@@ -1547,32 +1547,53 @@
           logger
+%0A                    
 .atInfo()%0A      
@@ -1596,16 +1596,26 @@
         
+      
+    
 .withInj
@@ -1634,32 +1634,42 @@
 (%0A              
+      
+    
 caller.getClassN
@@ -1681,32 +1681,42 @@
 ,%0A              
+      
+    
 caller.getMethod
@@ -1729,32 +1729,42 @@
 ,%0A              
+      
+    
 caller.getLineNu
@@ -1777,32 +1777,42 @@
 ,%0A              
+     
+     
 caller.getFileNa
@@ -1827,21 +1827,56 @@
         
-.log(
+          .log(%0A                        
 %22PROFILE
@@ -1878,32 +1878,42 @@
 OFILE: %256d %25s%22,%0A
+          
               Du
@@ -1986,54 +1986,85 @@
 n())
-;
+,
 %0A      
-return;%0A    %7D%0A    logger.atInfo().log(
+      () -%3E%0A                logger.atInfo().log(%0A                    
 %22PRO
@@ -2070,32 +2070,44 @@
 OFILE: %256d %25s%22,%0A
+            
         Duration
@@ -2170,16 +2170,17 @@
 ption())
+)
 ;%0A  %7D%0A%7D%0A

Remove a use of `Throwables.lazyStackTrace`.