package io.reactivex.backport.plugin;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.ASM5;

final class BackportingMethodCallRemapper extends ClassVisitor {
  public BackportingMethodCallRemapper(ClassVisitor cv) {
    super(ASM5, cv);
  }

  @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature,
      String[] exceptions) {
    MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
    if (mv == null) {
      return null;
    }
    return new MethodVisitor(ASM5, mv) {
      @Override
      public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
        if ("java/util/Collections".equals(owner) && "emptyIterator".equals(name)) {
          owner = "io/reactivex/internal/java/util/Collections";
          System.out.println(
              "  Mapping method java/util/Collections.emptyIterator to io/reactivex/internal/java/util/Collections.emptyIterator");
        }
        if ("java/lang/Long".equals(owner) && "compare".equals(name)) {
          owner = "io/reactivex/internal/java/lang/Long";
          System.out.println(
              "  Mapping method java/lang/Long.compare to io/reactivex/internal/java/lang/Long.compare");
        }
        if ("java/lang/Integer".equals(owner) && "compare".equals(name)) {
          owner = "io/reactivex/internal/java/lang/Integer";
          System.out.println(
              "  Mapping method java/lang/Integer.compare to io/reactivex/internal/java/util/Integer.compare");
        }
        //if ("java/lang/Iterable".equals(owner) && "forEach".equals(name)) {
        //  opcode = Opcodes.INVOKESTATIC;
        //  owner = "io/reactivex/internal/java/lang/Iterable";
        //  System.out.println(
        //      "  Mapping method java/lang/Iterable.forEach to io/reactivex/internal/java/util/Iterable.forEach");
        //}
        //if ("java/util/List".equals(owner) && "forEach".equals(name)) {
        //  opcode = Opcodes.INVOKESTATIC;
        //  owner = "io/reactivex/internal/java/lang/Iterable";
        //  System.out.println(
        //      "  Mapping method java/util/List.forEach to io/reactivex/internal/java/util/Iterable.forEach");
        //}
        //if ("java/util/LinkedList".equals(owner) && "forEach".equals(name)) {
        //  opcode = Opcodes.INVOKESTATIC;
        //  owner = "io/reactivex/internal/java/lang/Iterable";
        //  System.out.println(
        //      "  Mapping method java/util/LinkedList.forEach to io/reactivex/internal/java/util/Iterable.forEach");
        //}
        super.visitMethodInsn(opcode, owner, name, desc, itf);
      }
    };
  }
}

@@ -110,16 +110,50 @@
 Visitor;
+%0Aimport org.objectweb.asm.Opcodes;
 %0A%0Aimport
@@ -1648,34 +1648,32 @@
       %7D%0A        
-//
 if (%22java/lang/I
@@ -1724,34 +1724,32 @@
 ame)) %7B%0A        
-//
   opcode = Opcod
@@ -1765,34 +1765,32 @@
 STATIC;%0A        
-//
   owner = %22io/re
@@ -1827,36 +1827,111 @@
 rable%22;%0A        
+  
-//
+desc = %22(Ljava/lang/Iterable;Lio/reactivex/functions/Consumer;)V%22;%0A       
   
+ 
 System.out.print
@@ -1934,34 +1934,32 @@
 rintln(%0A        
-//
       %22  Mapping
@@ -2048,34 +2048,32 @@
 Each%22);%0A        
-//
 %7D%0A        //if (
@@ -2058,34 +2058,32 @@
       %7D%0A        
-//
 if (%22java/util/L
@@ -2130,34 +2130,32 @@
 ame)) %7B%0A        
-//
   opcode = Opcod
@@ -2171,34 +2171,32 @@
 STATIC;%0A        
-//
   owner = %22io/re
@@ -2233,34 +2233,109 @@
 rable%22;%0A        
-//
+  desc = %22(Ljava/lang/Iterable;Lio/reactivex/functions/Consumer;)V%22;%0A        
   System.out.pri
@@ -2340,34 +2340,32 @@
 rintln(%0A        
-//
       %22  Mapping
@@ -2450,34 +2450,32 @@
 Each%22);%0A        
-//
 %7D%0A        //if (
@@ -2468,18 +2468,16 @@
         
-//
 if (%22jav
@@ -2546,18 +2546,16 @@
         
-//
   opcode
@@ -2587,18 +2587,16 @@
         
-//
   owner 
@@ -2649,18 +2649,93 @@
         
-//
+  desc = %22(Ljava/lang/Iterable;Lio/reactivex/functions/Consumer;)V%22;%0A        
   System
@@ -2756,18 +2756,16 @@
         
-//
       %22 
@@ -2876,10 +2876,8 @@
     
-//
 %7D%0A  

Rewrite forEach default method calls to static helper.