/*
 * Copyright (C) 2009 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.googlecode.guice.bundle;

import static com.google.inject.name.Names.named;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.matcher.AbstractMatcher;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Random;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

/**
 * Test Guice from inside an OSGi bundle activator.
 *
 * @author mcculls@gmail.com (Stuart McCulloch)
 */
@SuppressWarnings("unused")
public class OSGiTestActivator implements BundleActivator {

  // varying visibilities to test our code-generation support

  public static class Undefined {}

  public interface A {}

  protected interface B {}

  interface C {}

  private interface D {}

  public static class AA implements A {

    public AA() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  protected static class AB implements A {

    public AB() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  static class AC implements A {

    public AC() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  private static class AD implements A {

    public AD() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  public static class BA implements B {

    protected BA() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  protected static class BB implements B {

    protected BB() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  static class BC implements B {

    protected BC() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  private static class BD implements B {

    protected BD() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  public static class CA implements C {

    CA() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  protected static class CB implements C {

    CB() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  static class CC implements C {

    CC() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  private static class CD implements C {

    CD() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  public static class DA implements D {

    @Inject
    private DA() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  protected static class DB implements D {

    @Inject
    private DB() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  static class DC implements D {

    @Inject
    private DC() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  private static class DD implements D {

    private DD() {}

    @Inject
    public void setA(Undefined undefined) {}

    @Inject
    protected void setB(Undefined undefined) {}

    @Inject
    void setC(Undefined undefined) {}

    @Inject
    private void setD(Undefined undefined) {}

    @Inject public Undefined a;

    @Inject protected Undefined b;

    @Inject Undefined c;

    @Inject private Undefined d;
  }

  enum Visibility {
    PUBLIC,
    PROTECTED,
    PACKAGE_PRIVATE,
    PRIVATE
  }

  static final Class<?>[] TEST_CLAZZES = {A.class, B.class, C.class, D.class};

  // registers all the class combinations
  static class TestModule extends AbstractModule {

    final Bundle bundle;

    TestModule(Bundle bundle) {
      this.bundle = bundle;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected void configure() {
      for (Class<?> api : TEST_CLAZZES) {
        for (Visibility visibility : Visibility.values()) {
          try {

            // this registers: A + PUBLIC -> AA, A + PROTECTED -> AB, etc...
            String suffix = TEST_CLAZZES[visibility.ordinal()].getSimpleName();
            Class imp = bundle.loadClass(api.getName() + suffix);
            bind(api).annotatedWith(named(visibility.name())).to(imp);

          } catch (ClassNotFoundException e) {
            throw new RuntimeException("Unable to load test class", e);
          }
        }
      }
    }
  }

  /*if[AOP]*/
  // applies method-interception to classes with enough visibility
  static class InterceptorModule extends AbstractModule {
    @Override
    protected void configure() {
      bindInterceptor(
          new AbstractMatcher<Class<?>>() {
            @Override
            public boolean matches(Class<?> clazz) {
              try {

                // the class and constructor must be visible
                int clazzModifiers = clazz.getModifiers();
                int ctorModifiers = clazz.getConstructor().getModifiers();
                return (clazzModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0
                    && (ctorModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;

              } catch (NoSuchMethodException e) {
                return false;
              }
            }
          },
          new AbstractMatcher<Method>() {
            @Override
            public boolean matches(Method method) {

              // the intercepted method must also be visible
              int methodModifiers = method.getModifiers();
              return (methodModifiers & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0;
            }
          },
          new org.aopalliance.intercept.MethodInterceptor() {
            @Override
            public Object invoke(org.aopalliance.intercept.MethodInvocation mi) throws Throwable {

              return mi.proceed();
            }
          });
    }
  }
  /*end[AOP]*/

  // called from OSGi when bundle starts
  @Override
  public void start(BundleContext context) throws BundleException {

    final Bundle bundle = context.getBundle();

    Injector injector = Guice.createInjector(new TestModule(bundle));
    /*if[AOP]*/
    Injector aopInjector = Guice.createInjector(new TestModule(bundle), new InterceptorModule());
    /*end[AOP]*/

    // test code-generation support
    for (Class<?> api : TEST_CLAZZES) {
      for (Visibility vis : Visibility.values()) {
        injector.getInstance(Key.get(api, named(vis.name())));
        /*if[AOP]*/
        aopInjector.getInstance(Key.get(api, named(vis.name())));
        /*end[AOP]*/
      }
    }

    // test injection of system class (issue 343)
    injector.getInstance(Random.class);
    /*if[AOP]*/
    aopInjector.getInstance(Random.class);
    /*end[AOP]*/
  }

  // called from OSGi when bundle stops
  @Override
  public void stop(BundleContext context) {}
}
