/*
 * Copyright 2002-2008 the original author or authors.
 *
 * 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 test.feature.lifecycle.bpp.sjc118;

import org.junit.Assert;
import org.junit.Test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;

import org.springframework.config.java.annotation.AutoBean;
import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.context.JavaConfigApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.common.beans.TestBean;


/** TODO: JAVADOC */
public class SimpleTests {

    @Test
    public void doesJcacProperlyHandleAutowiredBPPs() {
        JavaConfigApplicationContext ctx = new JavaConfigApplicationContext(AutowiredBPPConfig2.class);
        Assert.assertEquals("bpp was not autowired", "myCustomName", ctx.getBean(AutowiredBPP.class).getCustomName());
        Assert.assertEquals("testBean was not named", "myCustomName", ctx.getBean(TestBean.class).getName());
    }

    @Test
    public void doesXmlProperlyHandleAutowiredBPPs() {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("SimpleTests.xml", getClass());
        Assert.assertEquals("bpp was not autowired",
                            "myCustomName", ((AutowiredBPP) ctx.getBean("autowiredBPP")).getCustomName());
        Assert.assertEquals("testBean was not named",
                            "myCustomName", ((TestBean) ctx.getBean("testBean")).getName());
    }

    @Configuration
    public static class AutowiredBPPConfig {
        @Bean
        public TestBean testBean() { return new TestBean(); }
    }

    @Configuration
    public abstract static class AutowiredBPPConfig2 {
        @Bean
        public AutowiredBPP autowiredBPP() { return new AutowiredBPP(); }

        @Bean
        public String customName() { return "myCustomName"; }

        @AutoBean
        public abstract AutowiredAnnotationBeanPostProcessor aaBPP();

        @Bean
        public TestBean testBean() { return new TestBean(); }
    }
}

@Configuration
class SomeConfig {
    @Bean
    public TestBean testBean() { return new TestBean(); }
}

class AutowiredBPP implements BeanPostProcessor {

    private String customName;

    @Autowired
    public void setCustomName(String customName) { this.customName = customName; }

    public String getCustomName() { return customName; }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof TestBean)
            ((TestBean) bean).setName(customName);

        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; }
}
