package com.bocloud.ims.service.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.CloudProvider;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.HostSystem;
import com.bocloud.cmp.model.SnapshotModel;
import com.bocloud.cmp.model.VMBean;
import com.bocloud.cmp.provider.utils.IPAddress;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.Cluster;
import com.bocloud.ims.entity.resource.DataStore;
import com.bocloud.ims.entity.resource.DataStoreFile;
import com.bocloud.ims.entity.resource.Ip;
import com.bocloud.ims.entity.resource.Ip.IpStatus;
import com.bocloud.ims.entity.resource.IpPool;
import com.bocloud.ims.entity.resource.Network;
import com.bocloud.ims.entity.resource.NetworkCard;
import com.bocloud.ims.entity.resource.Resource;
import com.bocloud.ims.entity.resource.Server;
import com.bocloud.ims.entity.resource.ServerConfig;
import com.bocloud.ims.entity.resource.Snapshot;
import com.bocloud.ims.entity.resource.StoreHost;
import com.bocloud.ims.entity.resource.Switcher;
import com.bocloud.ims.entity.resource.Vdc;
import com.bocloud.ims.entity.resource.Volume;
import com.bocloud.ims.repository.resource.CloudServerRepository;
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.model.cmdb.CmdbRelation;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class SyncH3cUtils {

	private CloudServerRepository cloudServerRepository;
	private DataStoreRepository dataStoreRepository;
	private ServerRepository serverRepository;
	private SnapshotRepository snapshotRepository;
	private NetworkRepository networkRepository;
	private ClusterRepository clusterRepository;
	private StoreHostRepository storeHostRepository;
	private NetworkCardRepository networkCardRepository;
	private NetworkHostRepository networkHostRepository;
	private ServerConfigRepository serverConfigRepository;
	private ResourceRepository resourceRepository;
	private IpRepository ipRepository;
	private ImageRepository imageRepository;
	private VolumeRepository volumeRepository;
	private DataStoreFileRepository storeFileRepository;
	private SwitcherRepository switcherRepository;
	private VdcRepository vdcRepository;

	public SyncH3cUtils(CloudServerRepository cloudServerRepository, ServerRepository serverRepository,
			SnapshotRepository snapshotRepository, DataStoreRepository dataStoreRepository,
			NetworkRepository networkRepository, ClusterRepository clusterRepository,
			StoreHostRepository storeHostRepository, NetworkCardRepository networkCardRepository,
			NetworkHostRepository networkHostRepository, ServerConfigRepository serverConfigRepository,
			ResourceRepository resourceRepository, IpRepository ipRepository, ImageRepository imageRepository,
			VolumeRepository volumeRepository, DataStoreFileRepository dataStoreFileRepository,
			SwitcherRepository switcherRepository, VdcRepository vdcRepository) {
		super();
		this.cloudServerRepository = cloudServerRepository;
		this.serverRepository = serverRepository;
		this.snapshotRepository = snapshotRepository;
		this.dataStoreRepository = dataStoreRepository;
		this.networkRepository = networkRepository;
		this.clusterRepository = clusterRepository;
		this.storeHostRepository = storeHostRepository;
		this.networkCardRepository = networkCardRepository;
		this.networkHostRepository = networkHostRepository;
		this.serverConfigRepository = serverConfigRepository;
		this.resourceRepository = resourceRepository;
		this.ipRepository = ipRepository;
		this.imageRepository = imageRepository;
		this.volumeRepository = volumeRepository;
		this.storeFileRepository = dataStoreFileRepository;
		this.switcherRepository = switcherRepository;
		this.vdcRepository = vdcRepository;
	}

	/**
	 * 同步集群
	 *
	 * @param oldCluster
	 * @param newCluster
	 * @param userId
	 * @throws Exception
	 */
	public void mergeCluster(Cluster oldCluster, Cluster newCluster, Long userId) throws Exception {
		oldCluster.setMemUsed(newCluster.getMemUsed());
		oldCluster.setMemTotal(newCluster.getMemTotal());
		if (newCluster.getDiskUsed() != null) {
			oldCluster.setDiskUsed(new BigDecimal(newCluster.getDiskUsed())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		if (newCluster.getDiskTotal() != null) {
			oldCluster.setDiskTotal(new BigDecimal(newCluster.getDiskTotal())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		oldCluster.setCpuUsed(newCluster.getCpuUsed());
		oldCluster.setCpuTotal(newCluster.getCpuTotal());
		oldCluster.setCpuCore(newCluster.getCpuCore());
		oldCluster.setHostNum(newCluster.getHostNum());
		oldCluster.setTemplateNum(newCluster.getTemplateNum());
		oldCluster.setVmNum(newCluster.getVmNum());
		oldCluster.setName(newCluster.getName());
		oldCluster.setMenderId(userId);
		clusterRepository.update(oldCluster);
	}

	/**
	 * 同步宿主机
	 *
	 * @param oldHost
	 * @param newHost
	 * @param vendorId
	 * @param vdcId
	 * @param clusterId
	 * @param userId
	 * @throws Exception
	 */
	public void mergeHost(Server oldHost, HostSystem newHost, Long vendorId, Long vdcId, Long clusterId, Long userId,
			Map<String, Long> switcherMap) throws Exception {
		BeanUtils.copyProperties(newHost, oldHost);
		oldHost.setManageIp(newHost.getHostIp());
		oldHost.setVdcId(vdcId);
		oldHost.setClusterId(clusterId);
		oldHost.setVendorId(vendorId);
		oldHost.setMenderId(userId);
		serverRepository.update(oldHost);
		// 保存主机配置信息
		ServerConfig config = serverConfigRepository.getBySid(oldHost.getId());
		if (null != config) {
			if (newHost.getDiskTotal() != null) {
				config.setDiskCapacity(new BigDecimal(newHost.getDiskTotal())
						.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
			}
			config.setCpuHz(newHost.getCpuTotal());
			config.setMemoryCapacity(newHost.getMemTotal());
			config.setCpuAmount(newHost.getCpuNum());
			config.setCpuMode(newHost.getCpuModel());
			config.setCpuCore(newHost.getCpuCore());
			config.setCpuUsed(newHost.getCpuUsed());
			config.setMemUsed(newHost.getMemUsed());
			if (newHost.getDiskUsed() != null) {
				config.setDiskUsed(new BigDecimal(newHost.getDiskUsed())
						.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
			}
			config.setVendor(newHost.getVendor());
			config.setCpuMode(newHost.getCpuModel());
			serverConfigRepository.update(config);
		} else {
			addServerConfig(newHost, oldHost.getId());
		}
		Long hostId = oldHost.getId();
		// 处理IP地址
		if (!StringUtils.isEmpty(oldHost.getManageIp())) {
			Ip ipExist = ipRepository.checkExist(oldHost.getManageIp(), 0L, vendorId);
			if (null == ipExist) {
				Ip ip = new Ip(oldHost.getManageIp(), null, null, null, vendorId, IDFactory.instance().uuid(), null,
						IpStatus.used);
				ip.setCatalog("PM");
				ip.setTarget(hostId);
				ipRepository.save(ip);
			} else {
				ipExist.setCatalog("PM");
				ipExist.setTarget(hostId);
				ipRepository.update(ipExist);
			}
		}
		mergeStore(vendorId, hostId, JSONArray.parseArray(JSONObject.toJSONString(newHost.getDataStores()), DataStore.class), userId, vdcId);

		// 同步该宿主机和存储的关系
		mergeStoreHost(vendorId, hostId, "PM", JSONArray.parseArray(JSONObject.toJSONString(newHost.getDataStores()), DataStore.class));
		// 同步该宿主机下的网卡
		List<NetworkCard> cards = networkCardRepository.listByHost(hostId, "PM");
		syncNetworkCard(cards, JSONArray.parseArray(JSONObject.toJSONString(newHost.getNetcards()), NetworkCard.class), vendorId, hostId, userId, "PM", switcherMap);
	}

	public void mergeStore(Long vendorId, Long hostId, List<DataStore> newDataStores, Long userId, Long vdcId)
			throws Exception {
		List<DataStore> oldDataStores = dataStoreRepository.listByHost(hostId);
		Map<String, DataStore> oldDataStoreMap = Maps.newHashMap();
		for (DataStore oldDataStore : oldDataStores) {
			oldDataStoreMap.put(oldDataStore.getStoreVal(), oldDataStore);
		}
		if (ListTool.isEmpty(oldDataStores) && !ListTool.isEmpty(newDataStores)) {// 数据库不存在,则全部新增
			// 新增
			for (DataStore dataStore : newDataStores) {
				dataStore.preSave(userId, userId, vendorId, vdcId);
				dataStore.setStoreVal(dataStore.getName());
				dataStoreRepository.save(dataStore);
				mergeStoreFile(vendorId, vdcId, hostId, userId, dataStore, dataStore.getFiles(), true);
			}
		} else if (!ListTool.isEmpty(oldDataStores) && !ListTool.isEmpty(newDataStores)) {// 数据库存在
			// 同步数据存储更新新增
			for (DataStore dataStore : newDataStores) {
				if (oldDataStoreMap.containsKey(dataStore.getStoreVal())) {
					DataStore store = oldDataStoreMap.get(dataStore.getStoreVal());
					store.setName(dataStore.getName());
					store.setCapacity(dataStore.getCapacity());
					store.setFreeSpace(dataStore.getFreeSpace());
					store.setVdcId(vdcId);
					store.setMenderId(userId);
					store.setHostNum(dataStore.getHostNum());
					store.setVmNum(dataStore.getVmNum());
					store.setTemplateNum(dataStore.getTemplateNum());
					store.setStatus(dataStore.getStatus());
					mergeStoreFile(vendorId, vdcId, hostId, userId, store, dataStore.getFiles(), false);
					dataStoreRepository.update(store);
					oldDataStoreMap.remove(dataStore.getStoreVal());
				} else {
					dataStore.preSave(userId, userId, vendorId, vdcId);
					dataStoreRepository.save(dataStore);
					mergeStoreFile(vendorId, vdcId, hostId, userId, dataStore, dataStore.getFiles(), true);
				}
			}
			// 同步数据存储删除不存在于平台上的数据
			Iterator<DataStore> stores = oldDataStoreMap.values().iterator();
			while (stores.hasNext()) {
				DataStore store = stores.next();
				// 删除数据存储与主机关机
				storeHostRepository.deleteByStore(store.getId());
				dataStoreRepository.remove(store.getId(), userId);
				storeFileRepository.removeByDataStore(store.getId());
			}
		} else if (!ListTool.isEmpty(oldDataStores) && ListTool.isEmpty(newDataStores)) {// 数据库存在，该虚拟机不存在快照，则全部删除
			for (DataStore store : oldDataStores) {
				storeHostRepository.deleteByStore(store.getId());
				storeFileRepository.removeByDataStore(store.getId());
			}
			dataStoreRepository.removeByVdc(vdcId, userId);

		}

	}

	public void mergeStoreFile(Long vendorId, Long vdcId, Long hostId, Long userId, DataStore dataStore,
			List<DataStoreFile> files, boolean isAdd) throws Exception {
		if (isAdd) {
			if (!ListTool.isEmpty(files)) {
				addDataStoreFile(vendorId, vdcId, hostId, userId, dataStore, files);
			}
		} else {
			List<DataStoreFile> dataStoreFiles = storeFileRepository.listByDataStore(dataStore.getId());
			Map<String, DataStoreFile> oldStoreFileMap = new HashMap<>();
			for (DataStoreFile dataStoreFile : dataStoreFiles) {
				oldStoreFileMap.put(dataStoreFile.getName(), dataStoreFile);
			}
			if (ListTool.isEmpty(dataStoreFiles) && !ListTool.isEmpty(files)) { // add
				addDataStoreFile(vendorId, vdcId, hostId, userId, dataStore, files);
			} else if (!ListTool.isEmpty(dataStoreFiles) && !ListTool.isEmpty(files)) { // modify
				for (DataStoreFile file : files) {
					// 需要更新
					if (oldStoreFileMap.containsKey(file.getName())) {
						DataStoreFile dataStoreFile = oldStoreFileMap.get(file.getName());
						dataStoreFile.setSize(file.getSize());
						dataStoreFile.setMenderId(userId);
						storeFileRepository.update(dataStoreFile);
						oldStoreFileMap.remove(file.getName());
					} else {
						// 需要新增
						file.preSave(userId, userId, vendorId, vdcId, hostId, dataStore.getId());
						storeFileRepository.save(file);
					}
				}
				// 同步数据存储删除不存在于平台上的数据
				Iterator<DataStoreFile> storeFiles = oldStoreFileMap.values().iterator();
				while (storeFiles.hasNext()) {
					DataStoreFile storeFile = storeFiles.next();
					storeFileRepository.remove(storeFile.getId(), userId);
				}
			} else { // 需要删除
				storeFileRepository.removeByDataStore(dataStore.getId());
			}
		}
	}

	public void addDataStoreFile(Long vendorId, Long vdcId, Long hostId, Long userId, DataStore dataStore,
			List<DataStoreFile> files) throws Exception {
		for (DataStoreFile file : files) {
			file.preSave(userId, userId, vendorId, vdcId, hostId, dataStore.getId());
			storeFileRepository.save(file);
		}
	}

	/**
	 * 同步该主机和存储的关系
	 *
	 * @param vendorId
	 * @param hostId
	 * @param category
	 * @param newDatastores
	 * @throws Exception
	 */
	public void mergeStoreHost(Long vendorId, Long hostId, String category, List<DataStore> newDatastores)
			throws Exception {
		List<StoreHost> storeHosts = storeHostRepository.list(hostId, category);
		Map<String, StoreHost> oldStoreMap = Maps.newHashMap();
		for (StoreHost storeHost : storeHosts) {
			DataStore dataStore = dataStoreRepository.query(storeHost.getStoreId());
			if (null != dataStore) {
				oldStoreMap.put(dataStore.getStoreVal(), storeHost);
			}
		}
		if (!ListTool.isEmpty(newDatastores)) {
			for (DataStore datastore : newDatastores) {
				if (oldStoreMap.containsKey(datastore.getStoreVal())) {
					oldStoreMap.remove(datastore.getStoreVal());
					continue;
				} else {
					storeHostRepository.save(new StoreHost(datastore.getId(), hostId, vendorId, category));
				}
			}
		}
		for (String dataStore : oldStoreMap.keySet()) {
			storeHostRepository.delete(oldStoreMap.get(dataStore));
		}
	}

	/**
	 * 同步虚拟机
	 *
	 * @param oldServer
	 * @param newServer
	 * @param hostStatus
	 * @param vendorId
	 * @param hostId
	 * @param userId
	 * @param switchers
	 * @throws Exception
	 */
	public void mergeCloudServer(CloudServer oldServer, CloudServer newServer, String hostStatus, Long vendorId,
			Long hostId, Long userId, String type, List<Switcher> switchers, List<IpPool> pools) throws Exception {
		if (BocloudStatus.Server.BUILDING.name().equals(oldServer.getStatus())) {
			return;
		}
		Long serverId = oldServer.getId();
		String managerIp = oldServer.getManagerIp();
		String privateIps = oldServer.getPrivateIps();
		Long vdcId = oldServer.getVdcId();
		String resourceId = oldServer.getResourceId();
		Boolean isTemplate = oldServer.getIsTemplate();
		Boolean recycle = oldServer.getRecycle();
		VMBean bean = new VMBean();
		BeanUtils.copyProperties(newServer, bean);
		BeanUtils.copyProperties(bean, oldServer);
		oldServer.setVendorType(type);
		oldServer.setId(serverId);
		oldServer.setName(URLDecoder.decode(oldServer.getName(), "utf-8"));
		oldServer.setMenderId(userId);
		oldServer.setVendorId(vendorId);
		oldServer.setHostId(hostId);
		oldServer.setManagerIp(managerIp);
		oldServer.setPrivateIps(privateIps);
		oldServer.setVdcId(vdcId);
		oldServer.setResourceId(resourceId);
		oldServer.setRecycle(recycle);
		oldServer.setIsTemplate(isTemplate);
		StringBuilder dataStoreStringBuilder = new StringBuilder();
		List<Volume> diskDevices = newServer.getDiskDevices();
		if (!ListTool.isEmpty(diskDevices)) {
			for (Volume diskDevice : diskDevices) {
				dataStoreStringBuilder = dataStoreStringBuilder.append(diskDevice.getName()).append(",");
			}
		}
		if (dataStoreStringBuilder.length() > 0) {
			oldServer.setDatastores(dataStoreStringBuilder.substring(0, dataStoreStringBuilder.lastIndexOf(",")));
		}
		if (BocloudStatus.Server.STOPPED.name().equalsIgnoreCase(oldServer.getStatus())) {
			oldServer.setStatus(BocloudStatus.Server.STOPPED.name());
		}
		// 更新资源表
		List<String> ips = Lists.newArrayList();
		if (!StringUtils.isEmpty(oldServer.getPrivateIps()) && !StringUtils.isEmpty(newServer.getPrivateIps())) {
			List<JSONObject> objects = JSONObject.parseArray(newServer.getPrivateIps(), JSONObject.class);
			List<JSONObject> newIpList = Lists.newArrayList();
			for (JSONObject object : objects) {
				String address = object.getString("ip");
				if (StringUtils.isEmpty(address)) {
					continue;
				}
				String networkName = "";
				if (address.contains("###")) {
					String[] split = address.split("###");
					address = split[0];
					networkName = split[1];
				}
				// 处理IP
				Ip ipExist = ipRepository.checkExist(address, 0L, vendorId);
				if (null == ipExist) {
					IPAddress ipAddress = IPAddress.getIPAddress(address);
					Ip ip = new Ip(address, null, newServer.getGateway(), newServer.getDns(), vendorId,
							IDFactory.instance().uuid(), null, IpStatus.used);
					ip.setCatalog("VM");
					ip.setTarget(oldServer.getId());
					for (IpPool pool : pools) {
						boolean flag = ipAddress.isInPools(ip.getIp(),
								JSONArray.parseArray(pool.getPools(), String.class));
						if (flag) {
							ip.setPoolId(pool.getId());
							break;
						}
					}
					ipRepository.save(ip);
				}
				JSONObject newIpObj = new JSONObject();
				newIpObj.put("address", address);
				newIpObj.put("networkName", networkName);
				newIpList.add(newIpObj);
				ips.add(address);
			}
			oldServer.setPrivateIps(JSONArray.toJSONString(newIpList));
		} else {
			// 更新privateIps
			if (oldServer.getManagerIp() != null
					|| (oldServer.getManagerIp() == null && newServer.getManagerIp() != null)) {
				String updateIp = oldServer.getManagerIp();
				if (!StringUtils.isNotEmpty(updateIp)) {
					updateIp = newServer.getManagerIp();
				}
				List<Ip> ipList = Lists.newArrayList();
				Ip ip = ipRepository.checkExist(updateIp, 0L, vendorId);
				if (null == ip) {
					ip = new Ip(updateIp, null, newServer.getGateway(), newServer.getDns(), vendorId,
							IDFactory.instance().uuid(), null, IpStatus.used);
					ip.setCatalog("VM");
					ip.setTarget(oldServer.getId());
					IPAddress ipAddress = IPAddress.getIPAddress(ip.getIp());
					for (IpPool pool : pools) {
						boolean flag = ipAddress.isInPools(ip.getIp(),
								JSONArray.parseArray(pool.getPools(), String.class));
						if (flag) {
							ip.setPoolId(pool.getId());
							break;
						}
					}
					ipRepository.save(ip);
					ipList.add(ip);
					ips.add(ip.getIp());
				}
				oldServer.setPrivateIps(JSONObject.toJSONString(ipList));
			}
		}
		cloudServerRepository.update(oldServer);
		Resource resource = resourceRepository.query(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
				serverId);
		// 新增
		if (null == resource) {
			resource = new Resource(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(), serverId,
					JSONObject.toJSONString(ips), oldServer.getOsCategory(), vendorId);
			resource.preSave(oldServer.getName(), oldServer.getStatus(), userId, 0L, 0L);
			resource.setInventory(JSONObject.toJSONString(oldServer));
			resourceRepository.save(resource);
		} else {
			// 更新
			resource.setStatus(oldServer.getStatus());
			resource.setPrivateIps(JSONObject.toJSONString(ips));
			resource.setMenderId(userId);
			resource.setOsCategory(oldServer.getOsCategory());
			resourceRepository.update(resource);
		}
		// 同步该虚拟机下的网卡
		List<NetworkCard> oldCards = networkCardRepository.listByHost(serverId, "VM");
		syncNetworkCard(oldCards, newServer.getNetcards(), vendorId, serverId, userId, "VM", Maps.newHashMap());
		// 同步该虚拟机下的快照
		List<Snapshot> shots = snapshotRepository.listByVMid(serverId);
		syncSnapshot(shots, newServer.getSnapshots(), vendorId, serverId, userId);
		// 同步该虚拟机下的磁盘设备
		List<Volume> disks = volumeRepository.listByServerId(serverId);
		syncDiskDevice(disks, newServer.getDiskDevices(), vendorId, serverId, userId);
	}

	/**
	 * 同步虚拟机下磁盘设备信息
	 *
	 * @param oldDisks
	 * @param newDisks
	 * @param vendorId
	 * @param serverId
	 * @param userId
	 * @throws Exception
	 */
	public void syncDiskDevice(List<Volume> oldDisks, List<Volume> newDisks, Long vendorId, Long serverId, Long userId)
			throws Exception {
		// 该虚拟机下没有任何硬盘设备
		if (!ListTool.isEmpty(oldDisks) && ListTool.isEmpty(newDisks)) {
			volumeRepository.removeByServerId(serverId, userId);
		} else if (!ListTool.isEmpty(oldDisks) && !ListTool.isEmpty(newDisks)) {
			Map<String, Volume> oldMap = Maps.newHashMap();
			for (Volume disk : oldDisks) {
				String diskObjectId = serverId + "_" + disk.getName();
				oldMap.put(diskObjectId, disk);
			}
			for (Volume disk : newDisks) {
				String diskObjectId = serverId + "_" + disk.getName();
				if (oldMap.containsKey(diskObjectId)) {
					Volume oldDisk = oldMap.get(diskObjectId);
					oldDisk.setName(disk.getName());
					oldDisk.setMenderId(userId);
					if (disk.getSize() != null) {
						oldDisk.setSize(new BigDecimal(disk.getSize()).divide(new BigDecimal(1024)).intValue());
					}
					oldDisk.setDiskObjectId(diskObjectId);
					volumeRepository.update(oldDisk);
					oldMap.remove(diskObjectId);
				} else {
					addDisk(vendorId, serverId, userId, disk, diskObjectId);
					oldMap.remove(diskObjectId);
				}
			}
			Iterator<Volume> disks = oldMap.values().iterator();
			while (disks.hasNext()) {
				Long id = disks.next().getId();
				volumeRepository.remove(id, userId);
			}
		} else if (ListTool.isEmpty(oldDisks) && !ListTool.isEmpty(newDisks)) {
			for (Volume disk : newDisks) {
				String diskObjectId = serverId + "_" + disk.getName();
				addDisk(vendorId, serverId, userId, disk, diskObjectId);
			}
		}
	}

	public void addDisk(Long vendorId, Long serverId, Long userId, Volume disk, String diskObjectId) throws Exception {
		disk.preSave(userId, userId, 0L, vendorId);
		disk.setServerId(serverId);
		if (disk.getSize() != null) {
			disk.setSize(new BigDecimal(disk.getSize()).divide(new BigDecimal(1024)).intValue());
		}
		disk.setVolumeUuid(IDFactory.instance().uuid());
		disk.setDiskObjectId(diskObjectId);
		volumeRepository.save(disk);
	}

	/**
	 * 保存主机配置信息
	 *
	 * @param host
	 * @param serverId
	 * @throws Exception
	 */
	public ServerConfig addServerConfig(HostSystem host, Long serverId) throws Exception {
		ServerConfig config = new ServerConfig();
		if (host.getDiskTotal() != null) {
			config.setDiskCapacity(new BigDecimal(host.getDiskTotal())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		if (host.getDiskUsed() != null) {
			config.setDiskUsed(new BigDecimal(host.getDiskUsed())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		config.setCpuHz(host.getCpuTotal());
		config.setMemoryCapacity(host.getMemTotal());
		config.setCpuAmount(host.getCpuNum());
		config.setCpuMode(host.getCpuModel());
		config.setCpuCore(host.getCpuCore());
		config.setCpuUsed(host.getCpuUsed());
		config.setMemUsed(host.getMemUsed());

		config.setServerId(serverId);
		config.setVendor(host.getVendor());
		serverConfigRepository.save(config);
		return config;
	}

	/**
	 * 添加虚拟机及之下的快照信息
	 *
	 * @param vendorId
	 * @param hostId
	 * @param userId
	 * @param switchers
	 * @throws Exception
	 */
	public void addCloudServerCascade(CloudServer cloudServer, Long vendorId, Long hostId, Long vdcId, Long userId,
			String status, String type, List<Switcher> switchers, List<IpPool> pools) throws Exception {
		cloudServer.preSave(userId, userId, vendorId, hostId, vdcId, null, 0L, 0L);
		if (BocloudStatus.Server.STOPPED.name().equals(status)) {
			cloudServer.setStatus(BocloudStatus.Server.STOPPED.name());
		}
		cloudServer.setVendorType(type);
		cloudServer.setName(URLDecoder.decode(cloudServer.getName(), "utf-8"));
		cloudServer.setResourceId(IDFactory.instance().uuid());
		cloudServer.setRecycle(false);
		cloudServer.setIsTemplate(false);
		StringBuilder dataStoreStringBuilder = new StringBuilder();
		List<Volume> diskDevices = cloudServer.getDiskDevices();
		if (!ListTool.isEmpty(diskDevices)) {
			for (Volume diskDevice : diskDevices) {
				dataStoreStringBuilder = dataStoreStringBuilder.append(diskDevice.getName()).append(",");
			}
		}
		if (dataStoreStringBuilder.length() > 0) {
			cloudServer.setDatastores(dataStoreStringBuilder.substring(0, dataStoreStringBuilder.lastIndexOf(",")));
		}
		cloudServerRepository.save(cloudServer);
		Long serverId = cloudServer.getId();
		// 保存资源
		List<String> privateIps = Lists.newArrayList();
		if (!StringUtils.isEmpty(cloudServer.getPrivateIps())) {
			List<Ip> objects = JSONObject.parseArray(cloudServer.getPrivateIps(), Ip.class);
			List<JSONObject> newIpList = Lists.newArrayList();
			if (!ListTool.isEmpty(objects)) {
				for (Ip ipObj : objects) {
					String address = ipObj.getIp();
					if (StringUtils.isEmpty(address)) {
						continue;
					}
					String networkName = "";
					if (address.contains("###")) {
						String[] split = address.split("###");
						address = split[0];
						networkName = split[1];
					}
					privateIps.add(address);
					// 处理IP
					Ip ip = ipRepository.checkExist(address, 0L, vendorId);
					if (null == ip) {
						ip = new Ip(address, null, cloudServer.getGateway(), cloudServer.getDns(), vendorId,
								IDFactory.instance().uuid(), null, IpStatus.used);
						ip.setCatalog("VM");
						ip.setTarget(cloudServer.getId());
						IPAddress ipAddress = IPAddress.getIPAddress(address);
						for (IpPool pool : pools) {
							boolean flag = ipAddress.isInPools(ip.getIp(),
									JSONArray.parseArray(pool.getPools(), String.class));
							if (flag) {
								ip.setPoolId(pool.getId());
								break;
							}
						}
						ipRepository.save(ip);
					}
					JSONObject newIpObj = new JSONObject();
					newIpObj.put("address", address);
					newIpObj.put("networkName", networkName);
					newIpList.add(newIpObj);
				}
				cloudServer.setPrivateIps(JSONArray.toJSONString(newIpList));
				cloudServer.setGmtModify(new Date());
				cloudServer.setMenderId(userId);
				cloudServerRepository.update(cloudServer);
			}
		} else {
			if (cloudServer.getManagerIp() != null) {
				List<JSONObject> ips = new ArrayList<>();
				Ip ip = new Ip(cloudServer.getManagerIp(), null, cloudServer.getGateway(), cloudServer.getDns(),
						vendorId, IDFactory.instance().uuid(), null, IpStatus.used);
				ip.setCatalog("VM");
				ip.setTarget(cloudServer.getId());
				ipRepository.save(ip);
				JSONObject newIpObj = new JSONObject();
				newIpObj.put("ip", ip.getIp());
				ips.add(newIpObj);
				cloudServer.setPrivateIps(JSONObject.toJSONString(ips));
				cloudServerRepository.update(cloudServer);
				privateIps.add(cloudServer.getManagerIp());
			}
		}
		Resource resource = resourceRepository.query(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
				serverId);
		if (null == resource) {
			resource = new Resource(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(), serverId,
					JSONObject.toJSONString(privateIps), cloudServer.getOsCategory(), vendorId);
			resource.preSave(cloudServer.getName(), cloudServer.getStatus(), userId, 0L, 0L);
			resource.setInventory(JSONObject.toJSONString(cloudServer));
			resourceRepository.save(resource);
		} else {
			resource.setStatus(cloudServer.getStatus());
			resource.setPrivateIps(JSONObject.toJSONString(privateIps));
			resource.setMenderId(userId);
			resource.setOsCategory(cloudServer.getOsCategory());
			resourceRepository.update(resource);
		}

		// 同步网卡
		addCard(vendorId, serverId, userId, "VM", cloudServer.getNetcards(), Maps.newHashMap());
		// 同步快照
		addSnapshot(vendorId, serverId, userId, cloudServer.getSnapshots());
		// 增加磁盘设备
		addDiskDevice(vendorId, serverId, userId, cloudServer.getDiskDevices());
	}

	public void addDiskDevice(Long vendorId, Long serverId, Long userId, List<Volume> disks) throws Exception {
		if (!ListTool.isEmpty(disks)) {
			for (Volume disk : disks) {
				String diskObjectId = serverId + "_" + disk.getName();
				disk.preSave(userId, userId, 0L, vendorId);
				disk.setServerId(serverId);
				disk.setVolumeUuid(IDFactory.instance().uuid());
				if (disk.getSize() != null) {
					disk.setSize(new BigDecimal(disk.getSize()).divide(new BigDecimal(1024)).intValue());
				}
				disk.setDiskObjectId(diskObjectId);
				volumeRepository.save(disk);
			}
		}
	}

	public void addStore(Long vendorId, Long vdcId, Long hostId, List<DataStore> stores, Long userId) throws Exception {
		if (!ListTool.isEmpty(stores)) {
			for (DataStore store : stores) {
				store.preSave(userId, userId, vendorId, vdcId);
				dataStoreRepository.save(store);
				storeHostRepository.save(new StoreHost(store.getId(), hostId, vendorId, "PM"));
				List<DataStoreFile> files = store.getFiles();
				if (!ListTool.isEmpty(files)) {
					addDataStoreFile(vendorId, vdcId, hostId, userId, store, files);
				}
			}
		}
	}

	public void addCard(Long vendorId, Long hostId, Long userId, String category, List<NetworkCard> cards,
			Map<String, Long> switcherMap) throws Exception {
		if (ListTool.isEmpty(cards)) {
			return;
		}
		for (NetworkCard card : cards) {
			card.preSave(userId, userId, vendorId, hostId, category);
			if (!StringUtils.isEmpty(card.getSwitcher())) {
				card.setSwitcherId(switcherMap.get(card.getSwitcher()));
			}
			networkCardRepository.save(card);
		}
	}

	public void addSnapshot(Long vendorId, Long serverId, Long userId, List<Snapshot> snapshots) throws Exception {
		if (ListTool.isEmpty(snapshots)) {
			return;
		}
		for (Snapshot snapshot : snapshots) {
			snapshot.preSave(userId, userId, vendorId, serverId, 0L);
			snapshotRepository.save(snapshot);
		}
	}

	/**
	 * 同步网卡
	 *
	 * @param oldCards
	 * @param newCards
	 * @param vendorId
	 * @param hostId
	 * @param userId
	 * @throws Exception
	 */
	public void syncNetworkCard(List<NetworkCard> oldCards, List<NetworkCard> newCards, Long vendorId, Long hostId,
			Long userId, String category, Map<String, Long> switcherMap) throws Exception {
		if (ListTool.isEmpty(oldCards) && !ListTool.isEmpty(newCards)) {
			// 数据库不存在，该宿主机下存在网卡，则全部新增
			// 新增
			for (NetworkCard card : newCards) {
				card.preSave(userId, userId, vendorId, hostId, category);
				if (!StringUtils.isEmpty(card.getSwitcher())) {
					card.setSwitcherId(switcherMap.get(card.getSwitcher()));
				}
				networkCardRepository.save(card);
			}
		} else if (!ListTool.isEmpty(oldCards) && !ListTool.isEmpty(newCards)) {
			// 数据库存在，该宿主机存在网卡，则更新或新增
			Map<String, NetworkCard> oldCardMap = Maps.newHashMap();
			for (NetworkCard card : oldCards) {
				oldCardMap.put(card.getMac(), card);
			}
			// 同步网卡更新新增
			for (NetworkCard card : newCards) {
				if (oldCardMap.containsKey(card.getMac())) {
					NetworkCard netCard = oldCardMap.get(card.getMac());
					netCard.setName(card.getName());
					netCard.setMenderId(userId);
					netCard.setVendorId(vendorId);
					netCard.setHostId(hostId);
					netCard.setLabel(card.getLabel());
					netCard.setUsed(card.getUsed());
					netCard.setPortType(card.getPortType());
					if (!StringUtils.isEmpty(card.getSwitcher())) {
						netCard.setSwitcherId(switcherMap.get(card.getSwitcher()));
					} else {
						netCard.setSwitcherId(null);
					}
					networkCardRepository.update(netCard);
					// 移除存在更新的网卡
					oldCardMap.remove(card.getMac());
				} else {
					card.preSave(userId, userId, vendorId, hostId, category);
					if (!StringUtils.isEmpty(card.getSwitcher()) && card.getUsed()) {
						card.setSwitcherId(switcherMap.get(card.getSwitcher()));
					} else {
						card.setSwitcherId(null);
					}
					networkCardRepository.save(card);
				}
			}
			// 同步删除不存在的网卡
			Iterator<NetworkCard> cards = oldCardMap.values().iterator();
			while (cards.hasNext()) {
				networkCardRepository.remove(cards.next().getId(), userId);
			}
		} else if (!ListTool.isEmpty(oldCards) && ListTool.isEmpty(newCards)) {// 数据库存在，该虚拟机不存在网卡，则全部删除
			networkCardRepository.removeByHost(hostId, category, userId);
		}
	}

	/**
	 * 同步快照
	 *
	 * @param oldShots
	 * @param newShots
	 * @param vendorId
	 * @param vmId
	 * @param userId
	 * @throws Exception
	 */
	public void syncSnapshot(List<Snapshot> oldShots, List<Snapshot> newShots, Long vendorId, Long vmId, Long userId)
			throws Exception {
		if (ListTool.isEmpty(oldShots) && !ListTool.isEmpty(newShots)) {// 数据库不存在，该虚拟机下存在快照，则全部新增
			// 新增
			for (Snapshot snapshot : newShots) {
				snapshot.preSave(userId, userId, vendorId, vmId, 0L);
				if (snapshot.getCreateTime() == null) {
					snapshot.setCreateTime(snapshot.getGmtCreate() != null ? snapshot.getGmtCreate() : new Date());
				}
				snapshotRepository.save(snapshot);
			}
		} else if (!ListTool.isEmpty(oldShots) && !ListTool.isEmpty(newShots)) {
			// 数据库存在，该虚拟机下存在快照，则全部新增更新或删除
			Map<String, Snapshot> oldShot = Maps.newHashMap();
			for (Snapshot shot : oldShots) {
				oldShot.put(shot.getName(), shot);
			}
			// 同步快照更新新增
			for (Snapshot snapshot : newShots) {
				if (oldShot.containsKey(snapshot.getName())) {
					Snapshot shot = oldShot.get(snapshot.getName());
					Date createTime = shot.getCreateTime();
					if (createTime == null) {
						createTime = shot.getGmtCreate() != null ? shot.getGmtCreate() : new Date();
					}
					SnapshotModel bean = new SnapshotModel();
					BeanUtils.copyProperties(snapshot, bean);
					BeanUtils.copyProperties(bean, shot);
					shot.setMenderId(userId);
					shot.setVendorId(vendorId);
					shot.setVmId(vmId);
					shot.setCreateTime(createTime);
					snapshotRepository.update(shot);
					// 移除存在更新的快照
					oldShot.remove(snapshot.getName());
				} else {
					snapshot.preSave(userId, userId, vendorId, vmId, 0L);
					Date createTime = snapshot.getCreateTime();
					if (createTime == null) {
						createTime = snapshot.getGmtCreate() != null ? snapshot.getGmtCreate() : new Date();
					}
					snapshot.setCreateTime(createTime);
					snapshotRepository.save(snapshot);
				}
			}
			// 同步删除不存在的快照
			Iterator<Snapshot> shots = oldShot.values().iterator();
			while (shots.hasNext()) {
				snapshotRepository.remove(shots.next().getId(), userId);
			}
		} else if (!ListTool.isEmpty(oldShots) && ListTool.isEmpty(newShots)) {// 数据库存在，该虚拟机不存在快照，则全部删除
			snapshotRepository.removeByVm(vmId, userId);
		}
	}

	public void removeHostCascade(Server host, Long userId, List<CmdbInfo> infos) throws Exception {
		Long hostId = host.getId();
		networkHostRepository.deleteByHost(hostId, "PM");
		networkCardRepository.removeByHost(hostId, "PM", userId);
		switcherRepository.removeByHostId(hostId, userId);
		List<StoreHost> storeHosts = storeHostRepository.list(hostId, "PM");
		for (StoreHost storeHost : storeHosts) {
			Long storeId = storeHost.getStoreId();
			if (infos != null) {
				DataStore dataStore = dataStoreRepository.query(storeId);
				infos.add(CmdbInfoConvertor.getInfo(dataStore, "delete", null));
			}
			dataStoreRepository.remove(storeHost.getStoreId(), userId);
		}
		storeHostRepository.deleteByHost(hostId, "PM");
		List<CloudServer> servers = cloudServerRepository.listByHid(hostId);
		for (CloudServer server : servers) {
			snapshotRepository.removeByVm(server.getId(), userId);
			storeHostRepository.deleteByHost(server.getId(), "VM");
			networkHostRepository.deleteByHost(server.getId(), "VM");
			networkCardRepository.removeByHost(server.getId(), "VM", userId);
			resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
					userId);
			// 回收IP
			ipRepository.delete(server.getId(), "VM", server.getVendorId());
			// cmdb删除虚拟机
			if (infos != null) {
				infos.add(CmdbInfoConvertor.getInfo(server, "delete", null));
			}
		}
		storeFileRepository.removeByHost(hostId, userId);
		cloudServerRepository.removeByHost(hostId, userId);
		serverConfigRepository.removeBySid(hostId);
		resourceRepository.remove(hostId, ResourceCategory.Computer.name(), ResourceCatalog.PHYSICAL.name(), userId);
		serverRepository.remove(hostId, userId);
		// 回收IP
		ipRepository.delete(host.getId(), "PM", host.getVendorId());
		if (infos != null) {
			infos.add(CmdbInfoConvertor.getInfo(host, null, "delete", null));
		}

	}

	public CloudServerRepository getCloudServerRepository() {
		return cloudServerRepository;
	}

	public void setCloudServerRepository(CloudServerRepository cloudServerRepository) {
		this.cloudServerRepository = cloudServerRepository;
	}

	public DataStoreRepository getDataStoreRepository() {
		return dataStoreRepository;
	}

	public void setDataStoreRepository(DataStoreRepository dataStoreRepository) {
		this.dataStoreRepository = dataStoreRepository;
	}

	public ServerRepository getServerRepository() {
		return serverRepository;
	}

	public void setServerRepository(ServerRepository serverRepository) {
		this.serverRepository = serverRepository;
	}

	public SnapshotRepository getSnapshotRepository() {
		return snapshotRepository;
	}

	public void setSnapshotRepository(SnapshotRepository snapshotRepository) {
		this.snapshotRepository = snapshotRepository;
	}

	public NetworkRepository getNetworkRepository() {
		return networkRepository;
	}

	public void setNetworkRepository(NetworkRepository networkRepository) {
		this.networkRepository = networkRepository;
	}

	public ClusterRepository getClusterRepository() {
		return clusterRepository;
	}

	public void setClusterRepository(ClusterRepository clusterRepository) {
		this.clusterRepository = clusterRepository;
	}

	public StoreHostRepository getStoreHostRepository() {
		return storeHostRepository;
	}

	public void setStoreHostRepository(StoreHostRepository storeHostRepository) {
		this.storeHostRepository = storeHostRepository;
	}

	public NetworkCardRepository getNetworkCardRepository() {
		return networkCardRepository;
	}

	public void setNetworkCardRepository(NetworkCardRepository networkCardRepository) {
		this.networkCardRepository = networkCardRepository;
	}

	public NetworkHostRepository getNetworkHostRepository() {
		return networkHostRepository;
	}

	public void setNetworkHostRepository(NetworkHostRepository networkHostRepository) {
		this.networkHostRepository = networkHostRepository;
	}

	public ServerConfigRepository getServerConfigRepository() {
		return serverConfigRepository;
	}

	public void setServerConfigRepository(ServerConfigRepository serverConfigRepository) {
		this.serverConfigRepository = serverConfigRepository;
	}

	public ResourceRepository getResourceRepository() {
		return resourceRepository;
	}

	public void setResourceRepository(ResourceRepository resourceRepository) {
		this.resourceRepository = resourceRepository;
	}

	public IpRepository getIpRepository() {
		return ipRepository;
	}

	public void setIpRepository(IpRepository ipRepository) {
		this.ipRepository = ipRepository;
	}

	public ImageRepository getImageRepository() {
		return imageRepository;
	}

	public void setImageRepository(ImageRepository imageRepository) {
		this.imageRepository = imageRepository;
	}

	public VolumeRepository getVolumeRepository() {
		return volumeRepository;
	}

	public void setVolumeRepository(VolumeRepository volumeRepository) {
		this.volumeRepository = volumeRepository;
	}

	public DataStoreFileRepository getStoreFileRepository() {
		return storeFileRepository;
	}

	public void setStoreFileRepository(DataStoreFileRepository storeFileRepository) {
		this.storeFileRepository = storeFileRepository;
	}

	public void addHostCascade(Long vendorId, Long vdcId, Long clusterId, Long userId, String type, HostSystem host,
			List<CmdbInfo> infos, List<CmdbRelation> relations, List<IpPool> pools) throws Exception {
		Long hostId;
		Server server = new Server();
		BeanUtils.copyProperties(host, server);
		server.setManageIp(host.getHostIp());
		server.setResourceId(IDFactory.instance().uuid());
		server.preSave(userId, userId, vendorId, vdcId, clusterId);
		serverRepository.save(server);
		hostId = server.getId();
		// 处理IP地址
		if (!StringUtils.isEmpty(server.getManageIp())) {
			Ip ipExist = ipRepository.checkExist(server.getManageIp(), 0L, vendorId);
			if (null == ipExist) {
				Ip ip = new Ip(server.getManageIp(), null, null, null, vendorId, IDFactory.instance().uuid(), null,
						IpStatus.used);
				ip.setCatalog("PM");
				ip.setTarget(hostId);
				ipRepository.save(ip);
			} else {
				ipExist.setCatalog("PM");
				ipExist.setTarget(hostId);
				ipRepository.update(ipExist);
			}
		}
		// 保存主机配置信息
		ServerConfig config = addServerConfig(host, hostId);
		server.setConfig(config);
		// 保存资源
		List<String> privateIps = Lists.newArrayList();
		privateIps.add(server.getManageIp());
		Resource resource = new Resource(ResourceCategory.Computer.name(), ResourceCatalog.PHYSICAL.name(),
				server.getId(), JSONObject.toJSONString(privateIps), server.getCatalog(), vendorId);
		resource.preSave(server.getName(), server.getStatus(), userId, 0L, 0L);
		resource.setInventory(JSONObject.toJSONString(server));
		resourceRepository.save(resource);
		// 保存标准交换机
		Map<String, Long> switcherMap = Maps.newHashMap();
		Vdc vdc = vdcRepository.query(vdcId);
		syncSwitcher(null, JSONArray.parseArray(JSONObject.toJSONString(host.getSwitchers()), Switcher.class), vendorId,
				vdc, hostId, userId, type);
		List<Switcher> switchers = switcherRepository.listByHostId(hostId);
		// 保存物理网卡
		addCard(vendorId, hostId, userId, "PM",
				JSONArray.parseArray(JSONObject.toJSONString(host.getNetcards()), NetworkCard.class), switcherMap);
		// 保存虚拟机
		List<CloudServer> cloudServers = JSONArray.parseArray(JSONObject.toJSONString(host.getServers()),
				CloudServer.class);
		// h3cTransportor.syncCloudServer(oldServerMap, cloudServers, vendorId,
		// server.getId(), vdcId, userId,
		// server.getPowerState(), env, type);
		for (CloudServer cloudServer : cloudServers) {
			// 虚拟机与对象的关系
			cloudServer.setVendorType(type);
			this.addCloudServerCascade(cloudServer, vendorId, hostId, vdcId, userId, host.getPowerState(), type,
					switchers, pools);
		}

		// 宿主机和存储建立关系
		addStore(vendorId, vdcId, hostId, JSONArray.parseArray(JSONObject.toJSONString(host.getDataStores()),DataStore.class), userId);
		// 宿主机和网络建立关系
		// addNetwork(vendorId, hostId, "PM", host.getNetworks());
		// 同步到集群节点
		// if (null != clusterId) {
		// ClusterNode node = new ClusterNode(server.getManageIp(),
		// server.getResourceId(), "PM", clusterId);
		// node.setName(host.getName());
		// node.setCreatorId(userId);
		// node.setMenderId(userId);
		// node.setStatus(host.getStatus());
		// h3cTransportor.clusterNodeRepository.save(node);
		// }
		if (infos != null && relations != null) {
			infos.add(CmdbInfoConvertor.getInfo(server, config, null, relations));
		}
	}

	public void addCluster(Long vendorId, Long vdcId, Long userId, Cluster cluster) throws Exception {
		cluster.preSave(userId, userId, vendorId, vdcId);
		cluster.setType(CloudProvider.H3C.name());
		cluster.setUuid(IDFactory.instance().uuid());
		if (cluster.getDiskUsed() != null) {
			cluster.setDiskUsed(new BigDecimal(cluster.getDiskUsed())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		if (cluster.getDiskTotal() != null) {
			cluster.setDiskTotal(new BigDecimal(cluster.getDiskTotal())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		clusterRepository.save(cluster);
	}

	public void updateVdc(Long userId, Vdc vdc, Vdc oldVdc) throws Exception {
		oldVdc.setMenderId(userId);
		oldVdc.setCpuTotal(vdc.getCpuTotal());
		oldVdc.setCpuUsed(vdc.getCpuUsed());
		if (vdc.getDiskTotal() != null) {
			oldVdc.setDiskTotal(new BigDecimal(vdc.getDiskTotal())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		if (vdc.getDiskUsed() != null) {
			oldVdc.setDiskUsed(new BigDecimal(vdc.getDiskUsed())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		oldVdc.setMemTotal(vdc.getMemTotal());
		oldVdc.setMemUsed(vdc.getMemUsed());
		oldVdc.setName(vdc.getName());
		oldVdc.setType(CloudProvider.H3C.name());
		vdcRepository.update(oldVdc);
	}

	public void addVdc(Long userId, Long vendorId, Vdc vdc) throws Exception {
		vdc.preSave(userId, userId, vendorId);
		vdc.setUuid(vdc.getVdcVal());
		if (vdc.getDiskTotal() != null) {
			vdc.setDiskTotal(new BigDecimal(vdc.getDiskTotal())
					.divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
		}
		if (vdc.getDiskUsed() != null) {
			vdc.setDiskUsed(new BigDecimal(vdc.getDiskUsed()).divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP)
					.doubleValue());
		}
		vdc.setType(CloudProvider.H3C.name());
		vdcRepository.save(vdc);
	}

	/**
	 * 同步虚拟交换机 ，华三云 一个虚拟交换机对应一个网络, 一个网络下面只有一个子网
	 *
	 * @param oldSwitchers
	 * @param newSwitchers
	 * @param vendorId
	 * @param vdc
	 * @param hostId
	 * @param userId
	 * @param type
	 * @throws Exception
	 */
	public void syncSwitcher(List<Switcher> oldSwitchers, List<Switcher> newSwitchers, Long vendorId, Vdc vdc,
			Long hostId, Long userId, String type) throws Exception {
		if (!ListTool.isEmpty(oldSwitchers) && ListTool.isEmpty(newSwitchers)) {
			for (Switcher switcher : oldSwitchers) {
				networkCardRepository.release(switcher.getId(), userId);
				List<Network> networks = networkRepository.listBySwitcher(switcher.getId());
				for (Network network : networks) {
					syncNetwork(network, null, switcher.getId(), switcher.getName(), vendorId, vdc.getId(),
							vdc.getName(), userId);
				}

			}
			switcherRepository.removeByHostId(hostId, userId);

		} else {
			Map<String, Switcher> oldMap = Maps.newHashMap();
			if (!ListTool.isEmpty(oldSwitchers)) {
				for (Switcher switcher : oldSwitchers) {
					oldMap.put(switcher.getSwitcherVal(), switcher);
				}
			}
			for (Switcher switcher : newSwitchers) {
				if (oldMap.containsKey(switcher.getSwitcherVal())) {
					Switcher oldSwitcher = oldMap.get(switcher.getSwitcherVal());
					switcher.setId(oldSwitcher.getId());
					switcher.setGmtCreate(oldSwitcher.getGmtCreate());
					switcher.setGmtModify(new Date());
					switcher.setCreatorId(oldSwitcher.getCreatorId());
					switcher.setMenderId(userId);
					switcher.setDeleted(oldSwitcher.getDeleted());
					switcher.setHostId(oldSwitcher.getHostId());
					switcher.setVendorId(vendorId);
					switcher.setVdcId(vdc.getId());
					switcher.setType(type);
					BeanUtils.copyProperties(switcher, oldSwitcher);
					switcherRepository.update(oldSwitcher);
					// 处理network
					Network oldNetwork = null;
					List<Network> oldNetworks = networkRepository.listBySwitcher(switcher.getId());
					if (!ListTool.isEmpty(oldNetworks)) {
						oldNetwork = oldNetworks.get(0);
					}
					Network newNetwork = switcher.getNetwork();
					syncNetwork(oldNetwork, newNetwork, switcher.getId(), switcher.getName(), vendorId, vdc.getId(),
							vdc.getName(), userId);
					// 移除存在更新的交换机
					oldMap.remove(switcher.getSwitcherVal());
				} else {
					switcher.preSave(userId, userId, vendorId, vdc.getId(), hostId);
					switcher.setType("VSWITCH");
					switcherRepository.save(switcher);
					syncNetwork(null, switcher.getNetwork(), switcher.getId(), switcher.getName(), vendorId,
							vdc.getId(), vdc.getName(), userId);
				}
			}
			// 删除不存在的交换机
			Iterator<Switcher> switchers = oldMap.values().iterator();
			while (switchers.hasNext()) {
				Long switcherId = switchers.next().getId();
				networkCardRepository.release(switcherId, userId);
				switcherRepository.remove(switcherId, userId);
			}
		}
	}

	private void syncNetwork(Network oldNetwork, Network newNetwork, Long switcherId, String switcherName,
			Long vendorId, Long vdcId, String vdcName, Long userId) throws Exception {
		if (oldNetwork != null && newNetwork == null) {
			networkRepository.remove(oldNetwork.getId(), userId);
		} else if (oldNetwork != null && newNetwork != null) {
			oldNetwork.setSwitcherId(switcherId);
			oldNetwork.setName(switcherName);
			oldNetwork.setVdcName(vdcName);
			oldNetwork.preSave(userId, userId, vendorId, vdcId);
			oldNetwork.setGmtModify(new Date());
			networkRepository.update(oldNetwork);
		} else if (oldNetwork == null && newNetwork != null) {
			newNetwork.setName(switcherName);
			newNetwork.setSwitcherId(switcherId);
			newNetwork.setVdcId(vdcId);
			newNetwork.setVdcName(vdcName);
			newNetwork.setGmtCreate(new Date());
			newNetwork.setGmtModify(new Date());
			networkRepository.save(newNetwork);
		}
	}

}
