/**
 * Copyright (C) 2007 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;

import static com.google.inject.Asserts.assertContains;
import static com.google.inject.Asserts.getDeclaringSourcePart;
import static com.google.inject.Asserts.reserialize;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import junit.framework.TestCase;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * @author jessewilson@google.com (Jesse Wilson)
 */
@SuppressWarnings("UnusedDeclaration")
public class ProvisionExceptionTest extends TestCase {

  public void testExceptionsCollapsed() {
    try {
      Guice.createInjector().getInstance(A.class);
      fail(); 
    } catch (ProvisionException e) {
      assertTrue(e.getCause() instanceof UnsupportedOperationException);
      assertContains(e.getMessage(), "Error injecting constructor",
          "for parameter 0 at com.google.inject.ProvisionExceptionTest$C.setD",
          "for field at com.google.inject.ProvisionExceptionTest$B.c",
          "for parameter 0 at com.google.inject.ProvisionExceptionTest$A");
    }
  }

  /**
   * There's a pass-through of user code in the scope. We want exceptions thrown by Guice to be
   * limited to a single exception, even if it passes through user code.
   */
  public void testExceptionsCollapsedWithScopes() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(B.class).in(Scopes.SINGLETON);
        }
      }).getInstance(A.class);
      fail();
    } catch (ProvisionException e) {
      assertTrue(e.getCause() instanceof UnsupportedOperationException);
      assertFalse(e.getMessage().contains("custom provider"));
      assertContains(e.getMessage(), "Error injecting constructor",
          "for parameter 0 at com.google.inject.ProvisionExceptionTest$C.setD",
          "for field at com.google.inject.ProvisionExceptionTest$B.c",
          "for parameter 0 at com.google.inject.ProvisionExceptionTest$A");
    }
  }

  public void testMethodInjectionExceptions() {
    try {
      Guice.createInjector().getInstance(E.class);
      fail();
    } catch (ProvisionException e) {
      assertTrue(e.getCause() instanceof UnsupportedOperationException);
      assertContains(e.getMessage(), "Error injecting method",
          "at " + E.class.getName() + ".setObject(ProvisionExceptionTest.java:");
    }
  }

  public void testBindToProviderInstanceExceptions() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(D.class).toProvider(new DProvider());
        }
      }).getInstance(D.class);
      fail();
    } catch (ProvisionException e) {
      assertTrue(e.getCause() instanceof UnsupportedOperationException);
      assertContains(e.getMessage(),
          "1) Error in custom provider, java.lang.UnsupportedOperationException",
          "at " + ProvisionExceptionTest.class.getName(),
          getDeclaringSourcePart(getClass()));
    }
  }

  /**
   * This test demonstrates that if the user throws a ProvisionException, we wrap it to add context.
   */
  public void testProvisionExceptionsAreWrappedForBindToType() {
    try {
      Guice.createInjector().getInstance(F.class);
      fail();
    } catch (ProvisionException e) {
      assertContains(e.getMessage(), "1) User Exception",
          "at " + F.class.getName() + ".<init>(ProvisionExceptionTest.java:");
    }
  }

  public void testProvisionExceptionsAreWrappedForBindToProviderType() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(F.class).toProvider(FProvider.class);
        }
      }).getInstance(F.class);
      fail();
    } catch (ProvisionException e) {
      assertContains(e.getMessage(), "1) User Exception",
          "while locating ", FProvider.class.getName(),
          "while locating ", F.class.getName());
    }
  }

  public void testProvisionExceptionsAreWrappedForBindToProviderInstance() {
    try {
      Guice.createInjector(new AbstractModule() {
        protected void configure() {
          bind(F.class).toProvider(new FProvider());
        }
      }).getInstance(F.class);
      fail();
    } catch (ProvisionException e) {
      assertContains(e.getMessage(), "1) User Exception",
          "at " + ProvisionExceptionTest.class.getName(),
          getDeclaringSourcePart(getClass()));
    }
  }

  public void testProvisionExceptionIsSerializable() throws IOException {
    try {
      Guice.createInjector().getInstance(A.class);
      fail();
    } catch (ProvisionException expected) {
      ProvisionException reserialized = reserialize(expected);
      assertContains(reserialized.getMessage(),
          "1) Error injecting constructor, java.lang.UnsupportedOperationException",
              "at com.google.inject.ProvisionExceptionTest$RealD.<init>()",
              "at Key[type=com.google.inject.ProvisionExceptionTest$RealD, annotation=[none]]",
              "@com.google.inject.ProvisionExceptionTest$C.setD()[0]",
              "at Key[type=com.google.inject.ProvisionExceptionTest$C, annotation=[none]]",
              "@com.google.inject.ProvisionExceptionTest$B.c",
              "at Key[type=com.google.inject.ProvisionExceptionTest$B, annotation=[none]]",
              "@com.google.inject.ProvisionExceptionTest$A.<init>()[0]",
              "at Key[type=com.google.inject.ProvisionExceptionTest$A, annotation=[none]]");
    }
  }

  public void testMultipleCauses() {
    try {
      Guice.createInjector().getInstance(G.class);
      fail();
    } catch (ProvisionException e) {
      assertContains(e.getMessage(),
          "1) Error injecting method, java.lang.IllegalArgumentException",
          "Caused by: java.lang.IllegalArgumentException: java.lang.UnsupportedOperationException",
          "Caused by: java.lang.UnsupportedOperationException: Unsupported",
          "2) Error injecting method, java.lang.NullPointerException: can't inject second either",
          "Caused by: java.lang.NullPointerException: can't inject second either",
          "2 errors");
    }
  }

  public void testInjectInnerClass() throws Exception {
    Injector injector = Guice.createInjector();
    try {
      injector.getInstance(InnerClass.class);
      fail();
    } catch (Exception expected) {
      assertContains(expected.getMessage(),
          "Injecting into inner classes is not supported.",
          "while locating " + InnerClass.class.getName());
    }
  }

  public void testInjectLocalClass() throws Exception {
    class LocalClass {}

    Injector injector = Guice.createInjector();
    try {
      injector.getInstance(LocalClass.class);
      fail();
    } catch (Exception expected) {
      assertContains(expected.getMessage(),
          "Injecting into inner classes is not supported.",
          "while locating " + LocalClass.class.getName());
    }
  }

  public void testBindingAnnotationsOnMethodsAndConstructors() {
    try {
      Injector injector = Guice.createInjector();
      injector.getInstance(MethodWithBindingAnnotation.class);
      fail();
    } catch (ConfigurationException expected) {
      assertContains(expected.getMessage(), MethodWithBindingAnnotation.class.getName()
          + ".injectMe() is annotated with @", Green.class.getName() + "(), ",
          "but binding annotations should be applied to its parameters instead.",
          "while locating " + MethodWithBindingAnnotation.class.getName());
    }

    try {
      Guice.createInjector().getInstance(ConstructorWithBindingAnnotation.class);
      fail();
    } catch (ConfigurationException expected) {
      assertContains(expected.getMessage(), ConstructorWithBindingAnnotation.class.getName()
          + ".<init>() is annotated with @", Green.class.getName() + "(), ",
          "but binding annotations should be applied to its parameters instead.",
          "at " + ConstructorWithBindingAnnotation.class.getName() + ".class",
          "while locating " + ConstructorWithBindingAnnotation.class.getName());
    }
  }

  public void testBindingAnnotationWarningForScala() {
    Injector injector = Guice.createInjector(new AbstractModule() {
      protected void configure() {
        bind(String.class).annotatedWith(Green.class).toInstance("lime!");
      }
    });
    injector.getInstance(LikeScala.class);
  }

  public void testLinkedBindings() {
    Injector injector = Guice.createInjector(new AbstractModule() {
      protected void configure() {
        bind(D.class).to(RealD.class);
      }
    });

    try {
      injector.getInstance(D.class);
      fail();
    } catch (ProvisionException expected) {
      assertContains(expected.getMessage(),
          "at " + RealD.class.getName() + ".<init>(ProvisionExceptionTest.java:",
          "while locating " + RealD.class.getName(),
          "while locating " + D.class.getName());
    }
  }

  public void testProviderKeyBindings() {
    Injector injector = Guice.createInjector(new AbstractModule() {
      protected void configure() {
        bind(D.class).toProvider(DProvider.class);
      }
    });

    try {
      injector.getInstance(D.class);
      fail();
    } catch (ProvisionException expected) {
      assertContains(expected.getMessage(),
          "while locating " + DProvider.class.getName(),
          "while locating " + D.class.getName());
    }
  }

  private class InnerClass {}

  static class A {
    @Inject
    A(B b) { }
  }
  static class B {
    @Inject C c;
  }
  static class C {
    @Inject
    void setD(RealD d) { }
  }
  static class E {
    @Inject void setObject(Object o) {
      throw new UnsupportedOperationException();
    }
  }

  static class MethodWithBindingAnnotation {
    @Inject @Green void injectMe(String greenString) {}
  }

  static class ConstructorWithBindingAnnotation {
    @Inject @Green ConstructorWithBindingAnnotation(String greenString) {}
  }

  /**
   * In Scala, fields automatically get accessor methods with the same name. So we don't do
   * misplaced-binding annotation detection if the offending method has a matching field.
   */
  static class LikeScala {
    @Inject @Green String green;
    @Inject @Green String green() { return green; }
  }

  @Retention(RUNTIME)
  @Target({ FIELD, PARAMETER, CONSTRUCTOR, METHOD })
  @BindingAnnotation
  @interface Green {}

  interface D {}

  static class RealD implements D {
    @Inject RealD() {
      throw new UnsupportedOperationException();
    }
  }

  static class DProvider implements Provider<D> {
    public D get() {
      throw new UnsupportedOperationException();
    }
  }

  static class F {
    @Inject public F() {
      throw new ProvisionException("User Exception", new RuntimeException());
    }
  }

  static class FProvider implements Provider<F> {
    public F get() {
      return new F();
    }
  }

  static class G {
    @Inject void injectFirst() {
      throw new IllegalArgumentException(new UnsupportedOperationException("Unsupported"));
    }
    @Inject void injectSecond() {
      throw new NullPointerException("can't inject second either");
    }
  }
}
