package com.bocloud.ims.service.resource.h3c;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.ClusterDriver;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.model.ClusterModel;
import com.bocloud.cmp.model.ClusterOperateModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Cluster;
import com.bocloud.ims.entity.resource.Server;
import com.bocloud.ims.entity.resource.Vdc;
import com.bocloud.ims.interfaces.h3c.H3cClusterService;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ClusterRepository;
import com.bocloud.ims.repository.resource.DataStoreFileRepository;
import com.bocloud.ims.repository.resource.DataStoreRepository;
import com.bocloud.ims.repository.resource.ImageRepository;
import com.bocloud.ims.repository.resource.IpRepository;
import com.bocloud.ims.repository.resource.NetworkCardRepository;
import com.bocloud.ims.repository.resource.NetworkHostRepository;
import com.bocloud.ims.repository.resource.NetworkRepository;
import com.bocloud.ims.repository.resource.ResourceRepository;
import com.bocloud.ims.repository.resource.ServerConfigRepository;
import com.bocloud.ims.repository.resource.ServerRepository;
import com.bocloud.ims.repository.resource.SnapshotRepository;
import com.bocloud.ims.repository.resource.StoreHostRepository;
import com.bocloud.ims.repository.resource.SwitcherRepository;
import com.bocloud.ims.repository.resource.VdcRepository;
import com.bocloud.ims.repository.resource.VolumeRepository;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.ims.service.utils.SyncH3cUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service("h3cClusterService")
public class H3cClusterServiceImpl implements H3cClusterService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private CloudVendorRepository cloudVendorRepository;

	@Autowired
	private VdcRepository vdcRepository;

	@Autowired
	private ClusterRepository clusterRepository;

	@Autowired
	private ClusterDriver clusterDriver;

	@Autowired
	private ResourceEventPublisher resourceEventPublisher;

	@Autowired
	private ServerRepository serverRepository;
	@Autowired
	private CloudServerRepository cloudServerRepository;
	@Autowired
	private SnapshotRepository snapshotRepository;
	@Autowired
	private StoreHostRepository storeHostRepository;
	@Autowired
	private NetworkRepository networkRepository;
	@Autowired
	private NetworkCardRepository networkCardRepository;
	@Autowired
	private NetworkHostRepository networkHostRepository;
	@Autowired
	private ServerConfigRepository serverConfigRepository;
	@Autowired
	private ResourceRepository resourceRepository;
	@Autowired
	private IpRepository ipRepository;
	@Autowired
	private ImageRepository imageRepository;
	@Autowired
	private VolumeRepository volumeRepository;
	@Autowired
	private DataStoreFileRepository dataStoreFileRepository;
	@Autowired
	private SwitcherRepository switcherRepository;
	@Autowired
	private DataStoreRepository dataStoreRepository;

	@Override
	public BocloudResult create(ClusterOperateModel model, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(model.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			Vdc vdc = vdcRepository.query(model.getVdcId());
			if (null == vdc) {
				return new BocloudResult(false, "数据中心不存在");
			}
			boolean flag = clusterRepository.isExistInVendor(model.getClusterName(), vdc.getVendorId());
			if (flag) {
				return new BocloudResult(false, "该集群名称已存在");
			}
			new Thread(() -> {
				String operate = vendor.getType().toLowerCase() + ".cluster";
				String msgContent = "集群创建失败";
				// 设置为h3c hostpool的id
				ClusterOperateModel addModel = new ClusterOperateModel();
				BeanUtils.copyProperties(model, addModel);
				addModel.setVdcId(Long.valueOf(vdc.getVdcVal()));
				@SuppressWarnings("unchecked")
				BocloudResult<ClusterModel> result = clusterDriver.create(vendor.getUuid(), addModel);
				try {
					if (result.isSuccess()) {
						msgContent = "集群创建成功";
						// 同步集群
						String content = JSONObject.toJSONString(result.getData());
						ClusterModel clusterModel = JSONObject.parseObject(content, ClusterModel.class);
						Cluster cluster = new Cluster();
						cluster.setName(clusterModel.getName());
						cluster.setCreatorId(context.getTarget());
						cluster.setVendorId(vendor.getId());
						cluster.setMenderId(context.getTarget());
						cluster.setMemUsed(clusterModel.getMemUsed());
						cluster.setMemTotal(clusterModel.getMemTotal());
						cluster.setDiskUsed(clusterModel.getDiskUsed());
						cluster.setDiskTotal(clusterModel.getDiskTotal());
						cluster.setCpuUsed(clusterModel.getCpuUsed());
						cluster.setCpuTotal(clusterModel.getCpuTotal());
						cluster.setCpuCore(clusterModel.getCpuCore());
						cluster.setHostNum(clusterModel.getHostNum());
						cluster.setTemplateNum(0);
						cluster.setVmNum(clusterModel.getVmNum());
						cluster.setCpuExcessRatio(1L);
						cluster.setUuid(model.getVdcId().toString());
						cluster.setClusterVal(clusterModel.getClusterVal());
						cluster.setRemark(clusterModel.getRemark());
						cluster.setType(CloudProvider.H3C.name());
						cluster.preSave(context.getTarget(), context.getTarget(), vendor.getId(), model.getVdcId());
						clusterRepository.save(cluster);
						resourceEventPublisher.send(new OperateResult(true, msgContent, operate,
								MapTools.simpleMap("vendorId", vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					} else {
						logger.error(result.getMessage());
						resourceEventPublisher.send(new OperateResult(false, "集群创建失败", operate,
								MapTools.simpleMap("vendorId", vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				} catch (Exception e) {
					logger.error("Get error message:", e);
					msgContent = "集群创建失败";
					resourceEventPublisher.send(new OperateResult(false, msgContent, operate,
							MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
							context));
				}
			}).start();
			return new BocloudResult(true, "集群创建任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("create cluster error", e);
			return new BocloudResult(false, "创建集群失败");
		}
	}

	@Override
	public BocloudResult remove(Long clusterId, RequestContext context) {
		try {
			Cluster cluster = clusterRepository.query(clusterId);
			String clusterVal = cluster.getClusterVal();
			Long vendorId = cluster.getVendorId();
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			ClusterOperateModel model = new ClusterOperateModel();
			model.setClusterId(Long.valueOf(clusterVal));
			new Thread(() -> {
				String msgContent = "集群删除失败";
				String operate = vendor.getType().toLowerCase() + ".cluster";
				List<CmdbInfo> infos = new ArrayList<>();
				try {
					BocloudResult bocloudResult = clusterDriver.remove(vendor.getUuid(), model);
					if (bocloudResult.isSuccess()) {
						List<Server> servers = serverRepository.listByCluster(clusterId);
						boolean removed = clusterRepository.remove(clusterId, context.getTarget());
						if (removed) {
							if (!ListTool.isEmpty(servers)) {
								SyncH3cUtils syncH3cUtils = new SyncH3cUtils(cloudServerRepository, serverRepository,
										snapshotRepository, dataStoreRepository, networkRepository, clusterRepository,
										storeHostRepository, networkCardRepository, networkHostRepository,
										serverConfigRepository, resourceRepository, ipRepository, imageRepository,
										volumeRepository, dataStoreFileRepository, switcherRepository, vdcRepository);
								for (Server server : servers) {
									syncH3cUtils.removeHostCascade(server, context.getTarget(), infos);
								}
							}
							msgContent = "集群删除成功";
							resourceEventPublisher.send(new OperateResult(true, msgContent, operate,
									MapTools.simpleMap("vendorId", vendor.getId()),
									OperateResult.OperateCategory.ResourceEvent, context));
						} else {
							msgContent = "集群删除失败";
							resourceEventPublisher.send(new OperateResult(false, msgContent, operate,
									MapTools.simpleMap("vendorId", vendor.getId()),
									OperateResult.OperateCategory.ResourceEvent, context));
						}
					} else {
						msgContent = "集群删除失败";
						resourceEventPublisher.send(new OperateResult(false, msgContent, operate,
								MapTools.simpleMap("vendorId", vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				} catch (Exception e) {
					logger.error("Get error message:", e);
					msgContent = "集群删除失败";
					resourceEventPublisher.send(new OperateResult(false, msgContent, operate,
							MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
							context));

				}
			}).start();
			return new BocloudResult(true, "集群删除任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("create cluster error", e);
			return new BocloudResult(false, "删除集群失败");
		}
	}

}
