package com.bocloud.ims.service.scheduler.scheduler;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.ProviderRepository;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.Butler;
import com.bocloud.cmp.provider.ButlerRepository;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.OperateResult.OperateCategory;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.RequestContext.Catalog;
import com.bocloud.common.model.Result;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.common.User;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.core.CurrentService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 云供应商连接状态监听定时任务
 *
 * @author wangyu
 * @version 1.0
 * @since 2017年10月17日
 */
@Component
public class ProviderMonitorSchedule {

	private static Logger logger = LoggerFactory.getLogger(ProviderMonitorSchedule.class);
	@Autowired
	private CurrentService service;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private ProviderRepository providerRepository;
	@Autowired
	private ThreadPoolTaskExecutor taskExecutor;

	/**
	 * 轮询所有云平台连接状态，如果发现连接异常则发送消息给管理员
	 */
	@Scheduled(cron = "${provider.monitor.scheduler:0 0/33 * * * ?}")
	protected void monitor() {
		if (!service.isLeader()) {
			return;
		}
		logger.info("当前服务leader状态：{}", service.isLeader());
		taskExecutor.execute(() -> {
			List<String> providerTypes = Arrays.stream(CloudProvider.values()).map(CloudProvider::name)
					.collect(Collectors.toList());
			providerTypes.removeAll(Arrays.asList(CloudProvider.HILLSTONE.name(), CloudProvider.CAMPUS.name(),
					CloudProvider.JUMPSERVER.name()));

			List<CloudVendor> vendors = cloudVendorRepository.listByTypes(providerTypes, null);
			ButlerRepository repository = ButlerRepository.getInstance();
			for (CloudVendor vendor : vendors) {
				Result result;
				try {
					Butler butler = repository.get(vendor.getUuid());
					// 公有云加入地域
					JSONObject authentication = JSONObject.parseObject(vendor.getAuthentication());
					if (null != authentication && !StringUtils.isEmpty(authentication.getString("regions"))) {
						List<String> currentRegions = JSONObject.parseArray(authentication.getString("regions"),
								String.class);
						if (!ListTool.isEmpty(currentRegions)) {
							butler.setRegionId(currentRegions.get(0));
						}
					}
					result = providerRepository.accessable(butler);
				} catch (Exception e) {
					result = new Result(false, e.getMessage());
				}
				if (null == result) {
					return;
				}
				logger.info("{}[{}] === {} == {}", vendor.getType(), vendor.getName(), result.isSuccess(),
						result.getMessage());
				String operate = vendor.getType().toLowerCase() + ".provider";
				String content = "云平台【" + vendor.getName() + "】连接异常!";
				if (result.isSuccess() && BocloudStatus.Basic.ABNORMAL.name().equals(vendor.getStatus())) {// 连接正常
					vendor.setStatus(BocloudStatus.Basic.NORMAL.name());// 云平台连接正常
					content = "云平台【" + vendor.getName() + "】连接正常!";
					this.updateVendor(vendor, null, operate, content, result);
				} else if (result.isFailed() && BocloudStatus.Basic.NORMAL.name().equals(vendor.getStatus())) {// 平台连接正常
					vendor.setStatus(BocloudStatus.Basic.ABNORMAL.name());// 云平台连接异常
					this.updateVendor(vendor, null, operate, content, result);
				}
			}
		});
	}

	/**
	 * 更新云平台
	 *
	 * @param vendor
	 * @param users
	 * @param operate
	 * @param content
	 * @param result
	 */
	private void updateVendor(CloudVendor vendor, List<User> users, String operate, String content,
							  Result result) {
		cloudVendorRepository.update(vendor);
		logger.info("Cloud vendor 【" + vendor.getName() + "】 connect success!");
		if (null != users && users.size() > 0) {
			for (User user : users) {
				RequestContext context = new RequestContext(Catalog.Manager, user.getId(), 0L, 0L, null);
				resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
						MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateCategory.ResourceEvent, context));
			}
		}
		// 给admin发消息
		RequestContext context = new RequestContext(Catalog.Manager, 1L, 0L, 0L, null);
		resourceEventPublisher.send(new OperateResult(result.isSuccess(), content, operate,
				MapTools.simpleMap(Common.VENDORID, vendor.getId()), OperateCategory.ResourceEvent, context));
	}

}
