/*
 * Copyright (c) 2018. AxonIQ
 * 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 io.axoniq.axonhub.client.boot;


import io.axoniq.axonhub.client.AxonHubConfiguration;
import io.axoniq.axonhub.client.PlatformConnectionManager;
import io.axoniq.axonhub.client.command.AxonHubCommandBus;
import io.axoniq.axonhub.client.command.CommandPriorityCalculator;
import io.axoniq.axonhub.client.query.AxonHubQueryBus;
import io.axoniq.axonhub.client.query.QueryPriorityCalculator;
import org.axonframework.boot.autoconfig.AxonAutoConfiguration;
import org.axonframework.commandhandling.CommandBus;
import org.axonframework.commandhandling.SimpleCommandBus;
import org.axonframework.commandhandling.distributed.AnnotationRoutingStrategy;
import org.axonframework.common.transaction.TransactionManager;
import org.axonframework.messaging.interceptors.CorrelationDataInterceptor;
import org.axonframework.queryhandling.LoggingQueryInvocationErrorHandler;
import org.axonframework.queryhandling.QueryBus;
import org.axonframework.queryhandling.QueryInvocationErrorHandler;
import org.axonframework.queryhandling.SimpleQueryBus;
import org.axonframework.serialization.Serializer;
import org.axonframework.spring.config.AxonConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * Configures AxonHub as implementation for the CommandBus and QueryBus
 *
 * @author Marc Gathier
 */
@Configuration
@AutoConfigureBefore(AxonAutoConfiguration.class)
public class MessagingAutoConfiguration {
    @Bean
    public AxonHubConfiguration axonHubConfiguration() {
        return new AxonHubConfiguration();
    }

    @Bean
    public PlatformConnectionManager platformConnectionManager(AxonHubConfiguration routingConfiguration) {
        return new PlatformConnectionManager(routingConfiguration);
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean
    public CommandBus commandBus(TransactionManager txManager, AxonConfiguration axonConfiguration , AxonHubConfiguration axonHubConfiguration,
                                 Serializer serializer, PlatformConnectionManager platformConnectionManager, CommandPriorityCalculator priorityCalculator) {

        SimpleCommandBus commandBus = new SimpleCommandBus(txManager, axonConfiguration.messageMonitor(CommandBus.class, "commandBus"));
        commandBus.registerHandlerInterceptor(new CorrelationDataInterceptor<>(axonConfiguration.correlationDataProviders()));

        return new AxonHubCommandBus(platformConnectionManager, axonHubConfiguration, commandBus, serializer, new AnnotationRoutingStrategy(),
                priorityCalculator);
    }

    @Bean
    @ConditionalOnMissingBean
    public CommandPriorityCalculator commandPriorityCalculator() {
        return new CommandPriorityCalculator() {};
    }

    @Bean
    @ConditionalOnMissingBean
    public QueryPriorityCalculator queryPriorityCalculator() {
        return new QueryPriorityCalculator() {};
    }

    @Bean
    @ConditionalOnMissingBean
    public QueryInvocationErrorHandler queryInvocationErrorHandler() {
        return new LoggingQueryInvocationErrorHandler();
    }

    @Bean
    @ConditionalOnMissingBean
    public QueryBus queryBus(PlatformConnectionManager platformConnectionManager, AxonHubConfiguration axonHubConfiguration,
                             AxonConfiguration axonConfiguration,  TransactionManager txManager, Serializer serializer,
                             QueryPriorityCalculator priorityCalculator, QueryInvocationErrorHandler queryInvocationErrorHandler) {
        return new AxonHubQueryBus(platformConnectionManager, axonHubConfiguration,
                new SimpleQueryBus(axonConfiguration.messageMonitor(QueryBus.class, "queryBus"), txManager, queryInvocationErrorHandler),
                serializer, priorityCalculator);
    }

}


@@ -1728,32 +1728,81 @@
 nConfiguration;%0A
+import org.springframework.beans.BeansException;%0A
 import org.sprin
@@ -1930,24 +1930,139 @@
 issingBean;%0A
+import org.springframework.context.ApplicationContext;%0Aimport org.springframework.context.ApplicationContextAware;%0A
 import org.s
@@ -2434,118 +2434,485 @@
 ion 
-%7B%0A    @Bean%0A    public AxonHubConfiguration axonHubConfiguration() %7B%0A        return new AxonHubConfiguration()
+implements ApplicationContextAware %7B%0A    private ApplicationContext applicationContext;%0A%0A    @Bean%0A    public AxonHubConfiguration axonHubConfiguration() %7B%0A        AxonHubConfiguration configuration = new AxonHubConfiguration();%0A        configuration.setComponentName(clientName(applicationContext.getId()));%0A        return configuration;%0A    %7D%0A%0A    private String clientName(String id) %7B%0A        if( id.contains(%22:%22)) return id.substring(0, id.indexOf(%22:%22));%0A        return id
 ;%0A  
@@ -5110,11 +5110,186 @@
 %0A    %7D%0A%0A
+    @Override%0A    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException %7B%0A        this.applicationContext = applicationContext;%0A    %7D%0A
 %7D%0A%0A

Prepare for beta3 release (easier configuration for clients).