/**
 * 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.reserialize;
import java.io.IOException;
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 java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import junit.framework.TestCase;

/**
 * @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(), ".configure(ProvisionExceptionTest.java");
    }
  }

  /**
   * 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(), ".configure(ProvisionExceptionTest.java");
    }
  }

  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");
    }
  }
}
