/**
 * Copyright (C) 2008 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.inject.internal.util;

import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.getDeclaringSourcePart;

import com.google.inject.AbstractModule;
import com.google.inject.CreationException;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;

import junit.framework.TestCase;

import java.lang.reflect.Modifier;

/**
 * @author jessewilson@google.com (Jesse Wilson)
 */
public class LineNumbersTest extends TestCase {

  public void testLineNumbers() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(A.class);
        }
      });
      fail();
    } catch (CreationException expected) {
      assertContains(expected.getMessage(),
          "1) No implementation for " + B.class.getName() + " was bound.",
          "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
    }
  }

  static class A {
    @Inject A(B b) {}
  }
  public interface B {}

  /*if[AOP]*/
  public void testCanHandleLineNumbersForGuiceGeneratedClasses() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bindInterceptor(Matchers.only(A.class), Matchers.any(),
              new org.aopalliance.intercept.MethodInterceptor() {
                public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
                  return null;
                }
              });

          bind(A.class);
        }
      });
      fail();
    } catch (CreationException expected) {
      assertContains(expected.getMessage(),
          "1) No implementation for " + B.class.getName() + " was bound.",
          "for parameter 0 at " + A.class.getName() + ".<init>(LineNumbersTest.java:",
          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
    }
  }

  static class GeneratingClassLoader extends ClassLoader {
    static String name = "__generated";

    GeneratingClassLoader() {
      super(B.class.getClassLoader());
    }

    Class<?> generate() {
      org.objectweb.asm.ClassWriter cw =
          new org.objectweb.asm.ClassWriter(org.objectweb.asm.ClassWriter.COMPUTE_MAXS);
      cw.visit(org.objectweb.asm.Opcodes.V1_5,
          Modifier.PUBLIC, name, null,
          org.objectweb.asm.Type.getInternalName(Object.class), null);

      String sig = "("+org.objectweb.asm.Type.getDescriptor(B.class)+")V";

      org.objectweb.asm.MethodVisitor mv = cw.visitMethod(Modifier.PUBLIC, "<init>", sig, null, null);

      mv.visitAnnotation(org.objectweb.asm.Type.getDescriptor(Inject.class), true);
      mv.visitCode();
      mv.visitVarInsn(org.objectweb.asm.Opcodes.ALOAD, 0);
      mv.visitMethodInsn(org.objectweb.asm.Opcodes.INVOKESPECIAL,
          org.objectweb.asm.Type.getInternalName(Object.class), "<init>", "()V" );
      mv.visitInsn(org.objectweb.asm.Opcodes.RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
      cw.visitEnd();

      byte[] buf = cw.toByteArray();

      return defineClass(name.replace('/', '.'), buf, 0, buf.length);
    }
  }

  public void testUnavailableByteCodeShowsUnknownSource() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(new GeneratingClassLoader().generate());
        }
      });
      fail();
    } catch (CreationException expected) {
      assertContains(expected.getMessage(),
          "1) No implementation for " + B.class.getName() + " was bound.",
          "for parameter 0 at " + GeneratingClassLoader.name + ".<init>(Unknown Source)",
          "at " + LineNumbersTest.class.getName(), getDeclaringSourcePart(getClass()));
    }
  }
  
  public void testGeneratedClassesCanSucceed() {
    final Class<?> generated = new GeneratingClassLoader().generate();
    Injector injector = Guice.createInjector(new AbstractModule() {
      protected void configure() {
        bind(generated);
        bind(B.class).toInstance(new B() {});
      }
    });
    Object instance = injector.getInstance(generated);
    assertEquals(instance.getClass(), generated);
  }
  /*end[AOP]*/
}
