package com.pcloud.book;

import com.alibaba.druid.pool.DruidDataSource;
import com.pcloud.book.mq.config.MQTopicConumer;
import com.pcloud.common.core.constant.MQQueueConstant;
import com.pcloud.common.core.constant.MQTopicProducer;
import com.pcloud.common.core.datasource.DataSourceConfig;
import com.pcloud.common.core.mq.MQExchangeConstants;
import com.pcloud.common.core.mq.MQQueueConstants;
import com.pcloud.common.core.mq.RabbitMQFactory;
import org.apache.commons.lang3.BooleanUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.unit.DataSize;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import javax.servlet.MultipartConfigElement;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@ComponentScan("com.pcloud")
@EnableEurekaClient
@EnableFeignClients("com.pcloud")
@PropertySource({"classpath:properties/book.properties"})
@Configuration
@EnableSwagger2
@EnableScheduling
@MapperScan(basePackages = {"com.pcloud.book.*.mapper"}, sqlSessionFactoryRef = DataSourceConfig.SESSION_FACTORY_NAME)
public class BookApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookApplication.class, args);
    }

    @Bean
    public Docket createRestApi() {// 创建API基本信息
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(BooleanUtils.toBoolean(System.getProperty("swagger.enable", "false")))
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.pcloud"))// 扫描该包下的所有需要在Swagger中展示的API，@ApiIgnore注解标注的除外
                .paths(PathSelectors.any())
                .build();
    }

    @SuppressWarnings("deprecation")
    private ApiInfo apiInfo() {// 创建API的基本信息，这些信息会在Swagger UI中进行显示
        return new ApiInfoBuilder()
                .title("图书，融合版")// API 标题
                .description("图书，融合了spring-cloud & dubbo的接口")// API描述
                .contact("李莉")// 联系人
                .version("2.0.0")// 版本号
                .build();
    }

    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //允许上传的文件最大值
        factory.setMaxFileSize(DataSize.ofMegabytes(50)); //KB,MB
        /// 设置总上传数据总大小
        factory.setMaxRequestSize(DataSize.ofMegabytes(50));
        return factory.createMultipartConfig();
    }

    @Bean
    public DataSource setDataSourceProperties(@Autowired DataSource dataSource) {
        ArrayList<String> arr = new ArrayList<>();
        arr.add("set names utf8mb4;");
        ((DruidDataSource) dataSource).setConnectionInitSqls(arr);
        return dataSource;
    }

    @Bean
    public Queue deleteVideoQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.DELETE_VIDEO);
    }

    @Bean
    public Binding deleteVideoBind() {
        return RabbitMQFactory.bindingExchange(deleteVideoQueue(), MQTopicProducer.DELETE_VIDEO);
    }

    @Bean
    public Queue chooseDefaultChannelQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.CHOOSE_DEFAULT_CHANNEL);
    }

    @Bean
    public Binding chooseDefaultChannelBind() {
        return RabbitMQFactory.bindingExchange(chooseDefaultChannelQueue(), MQTopicProducer.CHOOSE_DEFAULT_CHANNEL);
    }


    @Bean
    public Queue registerPartyQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.REGISTER_PARTY);
    }

    @Bean
    public Binding registerPartyBind() {
        return RabbitMQFactory.bindingExchange(registerPartyQueue(), MQTopicProducer.REGISTER_PARTY);
    }

    @Bean
    public Queue genuineQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.GENUINE);
    }

    @Bean
    public Binding genuineBind() {
        return RabbitMQFactory.bindingExchange(genuineQueue(), MQTopicProducer.GENUINE);
    }

    @Bean
    public Queue paymentQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.PAYMENT);
    }

    @Bean
    public Binding paymentBind() {
        return RabbitMQFactory.bindingExchange(paymentQueue(), MQTopicProducer.PAYMENT);
    }

    @Bean
    public Queue addWXGroupQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.ADD_WXGROUP);
    }

    @Bean
    public Binding addWXGroupBind() {
        return RabbitMQFactory.bindingExchange(addWXGroupQueue(), MQTopicProducer.ADD_WXGROUP);
    }

    @Bean
    public Queue wxGroupSendTextQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.WXGROUP_SEND_TEXT);
    }

    @Bean
    public Binding wxGroupSendTextBind() {
        return RabbitMQFactory.bindingExchange(wxGroupSendTextQueue(), MQTopicProducer.WXGROUP_SEND_TEXT);
    }

    @Bean
    public Queue updateWXGroupNameQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.UPDATE_WXGROUP_NAME);
    }

    @Bean
    public Binding updateWXGroupNameBind() {
        return RabbitMQFactory.bindingExchange(updateWXGroupNameQueue(), MQTopicProducer.UPDATE_WXGROUP_NAME);
    }

    @Bean
    public Queue updateAppInfoQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.APP_UPDATE);
    }

    @Bean
    public Binding updateAppInfoBind() {
        return RabbitMQFactory.bindingExchange(updateAppInfoQueue(), MQTopicProducer.APP_UPDATE);
    }

    @Bean
    public Queue updateProductInfoQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.PRODUCT_UPDATE);
    }

    @Bean
    public Binding updateProductInfoBind() {
        return RabbitMQFactory.bindingExchange(updateProductInfoQueue(), MQTopicProducer.PRODUCT_UPDATE);
    }

    @Bean
    public Queue convert2BookQueue() {
        return RabbitMQFactory.queueBuilder(MQQueueConstant.CONVERT_TO_BOOK);
    }

    @Bean
    public Queue wxGroupLearningReportQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.WXGROUP_LEARNING_REPORT);
    }

    @Bean
    public Binding wxGroupLearningReportBind() {
        return RabbitMQFactory.bindingExchange(wxGroupLearningReportQueue(), MQTopicProducer.WXGROUP_LEARNING_REPORT);
    }

    /**
     * 微信个人机器人同意加好友
     */
    @Bean
    public Queue wxGroupAgreeAddUserQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.WX_AGREE_ADD_USER);
    }

    @Bean
    public Binding wxGroupAgreeAddUserBind() {
        return RabbitMQFactory.bindingExchange(wxGroupAgreeAddUserQueue(), MQTopicProducer.WX_AGREE_ADD_USER);
    }

    @Bean
    public Queue wxGroupUserBindQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.CONSUMER_WXGROUP_USER_BIND);
    }

    @Bean
    public Binding wxGroupUserBindBind() {
        return RabbitMQFactory.bindingExchange(wxGroupUserBindQueue(), MQTopicProducer.WXGROUP_USER_BIND);
    }


    @Bean
    public Queue wxLiveBroadcastReminderBindQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.WX_LIVE_BROADCAST_REMINDER);
    }

    @Bean
    public Binding wxLiveBroadcastReminderBindBind() {
        return RabbitMQFactory.bindingExchange(wxLiveBroadcastReminderBindQueue(), MQTopicProducer.WX_LIVE_BROADCAST_REMINDER);
    }

    @Bean
    public Queue someUserScanBookGroupQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.CONSUMER_SOME_USER_SCAN_BOOK_GROUP);
    }

    @Bean
    public Binding someUserScanBookGroupBind() {
        return RabbitMQFactory.bindingExchange(someUserScanBookGroupQueue(), MQTopicProducer.SOME_USER_SCAN_BOOK_GROUP);
    }

    @Bean
    public Queue wxGroupSendNotTextQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.WXGROUP_SEND_NOT_TEXT);
    }

    @Bean
    public Binding wxGroupSendNotTextBind() {
        return RabbitMQFactory.bindingExchange(wxGroupSendNotTextQueue(), MQTopicProducer.WXGROUP_SEND_NOT_TEXT);
    }

    /**
     * 监听小号真实状态
     */
    @Bean
    public Queue wxGroupRealStatusQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.ROBOT_REAL_STATUS);
    }

    @Bean
    public Binding wxGroupRealStatusBind() {
        return RabbitMQFactory.bindingExchange(wxGroupRealStatusQueue(), MQTopicProducer.ROBOT_REAL_STATUS);
    }

    @Bean
    public CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put(RabbitMQFactory.X_DELAYED_TYPE, RabbitMQFactory.DIRECT);
        return new CustomExchange(MQExchangeConstants.BOOK_DELAYED_EXCHANGE, RabbitMQFactory.X_DELAYED_MESSAGE, true, false, args);
    }

    /**
     * 创建一个立即消费队列
     */
    @Bean
    public Queue immediateQueue() {
        return new Queue(MQQueueConstants.BOOK_IMMEDIATE_QUEUE_FOR_DELAY, true);
    }

    /**
     * 把立即消费的队列和延时消费的exchange绑定在一起
     */
    @Bean
    public Binding bindingNotify() {
        return BindingBuilder.bind(immediateQueue()).to(delayExchange()).with(MQExchangeConstants.BOOK_DELAY_ROUTING_KEY).noargs();
    }

    @Bean
    public Queue selfRobotSendTextQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.SELF_ROBOT_SEND_TEXT);
    }

    @Bean
    public Binding selfRobotSendTextBind() {
        return RabbitMQFactory.bindingExchange(selfRobotSendTextQueue(),MQTopicProducer.SELF_ROBOT_SEND_TEXT);
    }

    @Bean
    public Queue tipQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.TIP_FOR_WECHAT_USER);
    }

    @Bean
    public Binding tipBind() {
        return RabbitMQFactory.bindingExchange(tipQueue(), MQTopicProducer.TIP_FOR_WECHAT_USER);
    }

    @Bean
    public Queue erpCreateBookQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.ERP_AUTO_CREATE_BOOK);
    }

    @Bean
    public Binding erpCreateBookBind() {
        return RabbitMQFactory.bindingExchange(erpCreateBookQueue(), MQTopicProducer.ERP_AUTO_CREATE_BOOK);
    }

    @Bean
    public Queue qrcodeBookUpdateQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.QRCODE_BOOK_UPDATE);
    }

    @Bean
    public Binding qrcodeBookUpdateBind() {
        return RabbitMQFactory.bindingExchange(qrcodeBookUpdateQueue(), MQTopicProducer.QRCODE_BOOK_UPDATE);
    }

    @Bean
    public Queue deleteQrcodeQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.DELETE_QRCODE);
    }

    @Bean
    public Binding deleteQrcodeBind() {
        return RabbitMQFactory.bindingExchange(deleteQrcodeQueue(), MQTopicProducer.DELETE_QRCODE);
    }

    @Bean
    public Queue recoverQrcodeQueue() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.RECOVER_QRCODE);
    }

    @Bean
    public Binding recoverQrcodeBind() {
        return RabbitMQFactory.bindingExchange(recoverQrcodeQueue(), MQTopicProducer.RECOVER_QRCODE);
    }

    /**
     * 支付记录
     *
     * @return
     */
    @Bean
    public Queue paymentExerciseBookTopic() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.PAYMENT_EXERCISE_BOOK);
    }

    @Bean
    public Binding paymentExerciseBookBind() {
        return RabbitMQFactory.bindingExchange(paymentExerciseBookTopic(), MQTopicProducer.EXERCISE_BOOK_PAY);
    }

    @Bean
    public Queue refundExerciseBookTopic() {
        return RabbitMQFactory.queueBuilder(MQTopicConumer.REFUND_EXERCISE_BOOK);
    }

    @Bean
    public Binding refundExerciseBookBind() {
        return RabbitMQFactory.bindingExchange(refundExerciseBookTopic(), MQTopicProducer.EXERCISE_BOOK_REFUND);
    }
}
