/**
 * 
 */
package com.platomix.userprofile;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;

import com.platomix.userprofile.handler.AbstractTagHandler;
import com.platomix.userprofile.handler.FlatTagHandler;
import com.platomix.userprofile.handler.core.CollectAllTagHandler;
import com.platomix.userprofile.handler.support.ForecastCancelTagManager;
import com.platomix.userprofile.handler.support.UserEventManager;
import com.platomix.userprofile.handler.support.UserTagManager;
import com.platomix.userprofile.handler.support.XxhTagManager;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author wookvn
 */
@Slf4j
@EnableCaching
@SpringBootApplication
public class Application {
	//全量运行时的handler  ！！注意！！ 一定要保证 collectAllTagHandler是最后一个
	static final String[] classHandlers=new String[]
			{ "xxhLongTagHandler", "xxhTagHandler", "xxhAppTagHandler", "xxhOrderTagHandler",
					"userOrderStateTagHandler", "orderSumDateTagHandler", "appPreferenceTagHandler",
					"complainTagHandler","forecastCancelTagHandler", "forecastOrderTagHandler"};
	//运行时需要取前2个月的handler
	static final String[] classPerHandlers=new String[]
			{ "xxhTagHandler", "xxhAppTagHandler","appPreferenceTagHandler"};
	/**
	 * # arg[0]=调用类别:
	 * 		zt_tag(生成标签) dic_tag（更新mysql字典表） xxh_etl（更新原始信息化etl数据到xxh表）
	 * 		z_cancel_data（准备退订数据） join_all（只合并宽表）  single_handler（单独调用 指定handler） 
	 * 	    multi_zttag_collect_join(生成/聚合/合并多个月标签)
	 * # arg[1]=月份: month
	 * # arg[2]=HandlerName: [比如：java -jar xxx.jar xxhAppTagHandler（使用类名的小写开头的字符串）]
	 *
	 */
	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
//		AbstractTagHandler tagHandler = applicationContext.getBean("activityJoinTagHandler",AbstractTagHandler.class);
//		tagHandler.handle("202204");
		//manager.tagCancelDataC4V2("202205");
//		AbstractTagHandler tagHandler = applicationContext.getBean("appPreferenceTagHandler", AbstractTagHandler.class);
//		tagHandler.handle("202204");

		//批量
//		tagHandler.handleMultiMonth("202111", false, 3);
//		//Flat表操作
//		FlatTagHandler tagHandler = applicationContext.getBean(FlatTagHandler.class);
//		tagHandler.tempDataToFlatView("202204");
		//运行程序
		if(args != null) log.info("===>>mainArgs:" + String.join(",", args));
		startProg(applicationContext,args);
//		applicationContext.close();
	}

	/**
	 * 根据args参数
	 * @param args
	 */
	static void startProg(ConfigurableApplicationContext applicationContext ,String[] args){
		//arg0 调用类别
		String sendTp = "";
		//arg1 月份
		String permonth = DateUtil.format(DateUtil.offsetMonth(new Date(), -1), "yyyyMM");
		String p_permonth =  DateUtil.format(DateUtil.offsetMonth(new Date(), -2), "yyyyMM");
		//arg2 HandlerName
		String handlerName = "";
		if (args != null && args.length > 0) {
			sendTp = args[0];
			if (args.length > 1) {
				permonth = args[1];
				//传值不需要 向前取一个月
				p_permonth=permonth;
				//p_permonth = DateUtil.format(DateUtil.offsetMonth(DateUtil.parse(permonth.substring(0, 4) + "-" + permonth.substring(4) + "-01", "yyyy-MM-dd"), -1), "yyyyMM");
			}
			if (args.length > 2) {
				handlerName = args[2];
			}
		}

		try{
			/**
			 * 生成指定月份全部标签（不传月份参数会默认跑前一个月的标签）
			 */
			if (sendTp.equals("zt_tag")) {
				for (Integer i = 0; i < classHandlers.length; i++) {
					AbstractTagHandler tagHandler = applicationContext.getBean(classHandlers[i], AbstractTagHandler.class);
					if (Arrays.asList(classPerHandlers).contains(classHandlers[i])) {
						tagHandler.handle(p_permonth);
					} else {
						tagHandler.handle(permonth);
					}
				}
				//生成rfm表 todo
			}
			/**
			 * 单独调用指定handler
			 */
			if (sendTp.equals("single_handler")) {
				AbstractTagHandler tagHandler = applicationContext.getBean(handlerName, AbstractTagHandler.class);
				tagHandler.handle(permonth);
			}
			/**
			 * 更新mysql中的字典表
			 */
			if (sendTp.equals("dic_tag")) {
				UserEventManager userEventHandler = applicationContext.getBean(UserEventManager.class);
				userEventHandler.genEventPropToMysql();
				UserTagManager manager = applicationContext.getBean(UserTagManager.class);
				manager.genSomeTagToMysql();
			}
			/**
			 * 更新etl2->xxh
			 */
			if (sendTp.equals("xxh_etl")) {
				XxhTagManager xxhTagManager = applicationContext.getBean(XxhTagManager.class);
				xxhTagManager.xxhFromEtlSp(permonth);
			}
			/**
			 * 退订订ding
			 */
			//退订数据准备  先调用这个准备数据，然后取TensorFlow训练，并预测 ？月结果
			if (sendTp.equals("z_cancel_data")) {
				ForecastCancelTagManager manager = applicationContext.getBean(ForecastCancelTagManager.class);
				manager.tagCancelDataC4(permonth,-1,true);
				manager.tagCancelDataC4V2(permonth);
			}
			/**
			 * 从135 向新的库拷贝
			 */
			if (sendTp.equals("copy_table")) {
				XxhTagManager tagHandler = applicationContext.getBean(XxhTagManager.class);

				if (args != null && args.length > 0) {
					String sql = args[1];
					try {
						tagHandler.createTables(sql);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}

			if(sendTp.equals("collect_all_tag")){
				applicationContext.getBean("collectAllTagHandler", AbstractTagHandler.class).handle(permonth);
			}
			if(sendTp.equals("join_all")){
				FlatTagHandler flatTagHandler = applicationContext.getBean(FlatTagHandler.class);
				flatTagHandler.tempDataToFlatView(permonth);
			}
			//聚合，合并多个月的标签数据
			if(sendTp.equals("multi_zttag_collect_join")) {
				//从jvm参数中获取月份间隔 java -DmonthInterval=xx -jar xxx.jar
				int monthInterval = NumberUtil.parseInt(System.getProperty("monthInterval"));
				if(monthInterval <= 0) { //不传递月份间隔，计算[当前月-paramMonth]=N个月
					Date paramMonthDate = DateUtil.parse(permonth, "yyyyMM");
					Date perMonthDate = DateUtil.offsetMonth(new Date(), -1);
					monthInterval = (int)DateUtil.betweenMonth(paramMonthDate, perMonthDate, false) + 1;
				}
				LocalDate monthDate = LocalDate.parse(permonth+"01", DateTimeFormatter.BASIC_ISO_DATE);
				for(int i = 0; i < monthInterval; i++) {
					String monthStr = DateUtil.format(monthDate.plusMonths(i).atStartOfDay(), "yyyyMM");
					//批量执行多个月份
					for(String classHandler : classHandlers) {
						//Long中间表只需要跑一次【跑多个月标签数据之前，先跑一次Long中间表】
						if(!"xxhLongTagHandler".equalsIgnoreCase(classHandler)) {
							AbstractTagHandler tagHandler = applicationContext.getBean(classHandler, AbstractTagHandler.class);
							tagHandler.handle(monthStr);
						}
					}
					//聚合标签
					applicationContext.getBean(CollectAllTagHandler.class).handle(monthStr);
					//合并标签
					applicationContext.getBean(FlatTagHandler.class).tempDataToFlatView(monthStr);
				}
			}
		}catch (Exception e){
			log.error(e.getMessage(), e);
		}
	}
}