package com.bocloud.ims.service.transporter.vendor;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.common.LocationDriver;
import com.bocloud.cmp.model.kubernetes.ContainerModel;
import com.bocloud.cmp.model.kubernetes.DaemonSetModel;
import com.bocloud.cmp.model.kubernetes.DeploymentModel;
import com.bocloud.cmp.model.kubernetes.KubernetesSyncModel;
import com.bocloud.cmp.model.kubernetes.NamespaceModel;
import com.bocloud.cmp.model.kubernetes.NodeModel;
import com.bocloud.cmp.model.kubernetes.PersistentVolumeClaimModel;
import com.bocloud.cmp.model.kubernetes.PersistentVolumeModel;
import com.bocloud.cmp.model.kubernetes.PodModel;
import com.bocloud.cmp.model.kubernetes.SecretModel;
import com.bocloud.cmp.model.kubernetes.ServiceModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
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.kubernetes.KubeContainer;
import com.bocloud.ims.entity.resource.kubernetes.KubeDaemonSet;
import com.bocloud.ims.entity.resource.kubernetes.KubeDeployment;
import com.bocloud.ims.entity.resource.kubernetes.KubeNamespace;
import com.bocloud.ims.entity.resource.kubernetes.KubeNode;
import com.bocloud.ims.entity.resource.kubernetes.KubePersistentVolume;
import com.bocloud.ims.entity.resource.kubernetes.KubePersistentVolumeClaim;
import com.bocloud.ims.entity.resource.kubernetes.KubePod;
import com.bocloud.ims.entity.resource.kubernetes.KubeSecret;
import com.bocloud.ims.entity.resource.kubernetes.KubeService;
import com.bocloud.ims.repository.kubernetes.KubeContainerRepository;
import com.bocloud.ims.repository.kubernetes.KubeDaemonSetRepository;
import com.bocloud.ims.repository.kubernetes.KubeDeploymentRepository;
import com.bocloud.ims.repository.kubernetes.KubeNamespaceRepository;
import com.bocloud.ims.repository.kubernetes.KubeNodeRepository;
import com.bocloud.ims.repository.kubernetes.KubePersistentVolumeClaimRepository;
import com.bocloud.ims.repository.kubernetes.KubePersistentVolumeRepository;
import com.bocloud.ims.repository.kubernetes.KubePodRepository;
import com.bocloud.ims.repository.kubernetes.KubeSecretRepository;
import com.bocloud.ims.repository.kubernetes.KubeServiceRepository;
import com.bocloud.ims.service.transporter.ResourceTransporter;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * k8s 同步
 */
@Component
public class KubernetesTransporter implements ResourceTransporter {

	private static Logger logger = LoggerFactory.getLogger(KubernetesTransporter.class);

	@Autowired
	private KubeNamespaceRepository namespaceRepository;
	@Autowired
	private KubeNodeRepository nodeRepository;
	@Autowired
	private KubePodRepository podRepository;
	@Autowired
	private KubeServiceRepository serviceRepository;
	@Autowired
	private KubeDeploymentRepository kubeDeploymentRepository;
	@Autowired
	private KubePersistentVolumeRepository persistentVolumeRepository;
	@Autowired
	private KubePersistentVolumeClaimRepository persistentVolumeClaimRepository;
	@Autowired
	private KubeContainerRepository kubeContainerRepository;
	@Autowired
	private KubeDaemonSetRepository kubeDaemonSetRepository;
	@Autowired
	private KubeSecretRepository kubeSecretRepository;
	@Autowired
    private LocationDriver locationDriver;

	@Override
	public BocloudResult transport(CloudVendor vendor, Long userId) {
		try {
			
			BocloudResult bocloudResult = this.locationDriver.sync(vendor.getUuid());
            if(bocloudResult.isFailed()) {
            	return bocloudResult;
            }
            Assert.notNull(bocloudResult.getData(), "数据同步异常！");
            Long vendorId = vendor.getId();
			
			if (null != bocloudResult.getData()) {
				String content = JSONObject.toJSONString(bocloudResult.getData());
				KubernetesSyncModel syncModel = JSONObject.parseObject(content, KubernetesSyncModel.class);
				// 同步namespace
				logger.info("start sync namespace ... ");
				List<NamespaceModel> namespaceModels = syncModel.getNamespaceModels();
				this.syncNamespace(namespaceModels, vendor, userId);
				Map<String, KubeNamespace> nsMap = new HashMap<String, KubeNamespace>();
				List<KubeNamespace> namespaces = namespaceRepository.listByVendor(vendor.getId());
				for (KubeNamespace kubeNamespace : namespaces) {
					nsMap.put(kubeNamespace.getName(), kubeNamespace);
				}
				logger.info("end sync namespace ... ");
				// 同步node
				logger.info("start sync node ... ");
				List<NodeModel> nodeModels = syncModel.getNodeModels();
				this.syncNode(nodeModels, vendor, userId);
				Map<String, KubeNode> nodeMap = new HashMap<String, KubeNode>();
				List<KubeNode> nodes = nodeRepository.listByVendor(vendor.getId());
				for (KubeNode kubeNode : nodes) {
					nodeMap.put(kubeNode.getName(), kubeNode);
				}
				logger.info("end sync node ... ");
				// 同步service
				logger.info("start sync service ... ");
				List<ServiceModel> serviceModels = syncModel.getServiceModels();
				this.syncService(serviceModels, vendor, userId, nsMap);
				Map<String, KubeService> serviceMap = new HashMap<String, KubeService>();
				List<KubeService> services = serviceRepository.listByVendor(vendor.getId());
				for (KubeService service : services) {
					serviceMap.put(service.getName() + service.getNamespace(), service);
				}
				logger.info("end sync service ... ");
				// 同步 deployment
				logger.info("start sync deployment ... ");
				List<DeploymentModel> deploymentModels = syncModel.getDeploymentModels();
				this.syncDeployment(deploymentModels, vendor, userId, nsMap);
				logger.info("end sync deployment ... ");

				logger.info("start sync daemonSet ... ");
				List<DaemonSetModel> daemonSetModels = syncModel.getDaemonSetModels();
				this.syncDaemonSetModel(daemonSetModels, vendor, userId, nsMap);
				logger.info("end sync daemonSet ... ");

				// 同步pod
				logger.info("start sync pod ... ");
				List<PodModel> podModels = syncModel.getPodModels();
				this.syncPod(podModels, vendor, userId, nsMap, nodeMap, serviceMap);
				logger.info("end sync pod ... ");
				// 同步 持久化存储卷
				logger.info("start sync PersistentVolume ... ");
				List<PersistentVolumeModel> persistentModels = syncModel.getPersistentModels();
				this.syncPersistentModels(persistentModels, vendor, userId, nsMap);
				logger.info("end sync PersistentVolume ... ");
				// 同步 PVC存储卷
				logger.info("start sync PersistentVolumeClaim ... ");
				List<PersistentVolumeClaimModel> persistentVolumeClaimModels = syncModel
						.getPersistentVolumeClaimModels();
				this.syncPersistentVolumeClaimModels(persistentVolumeClaimModels, vendor, userId, nsMap);
				logger.info("end sync PersistentVolumeClaim ... ");
				// 同步 Secret存储卷
				logger.info("start sync Secret ... ");
				List<SecretModel> secretModels = syncModel.getSecretModels();
				this.syncSecretModels(secretModels, vendor, userId, nsMap);
				logger.info("end sync Secret ... ");

			}
			return new BocloudResult(true, "云平台【" + vendor.getName() + "】平台数据同步成功");
		} catch (Exception e) {
			logger.error("Get error message:", e);
			return new BocloudResult(false, "云平台【" + vendor.getName() + "】平台数据同步失败:" + e.getMessage());
		}
	}

	private void syncSecretModels(List<SecretModel> secretModels, CloudVendor vendor, Long userId,
			Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(secretModels)) {
			kubeSecretRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeSecret> listByVendor = kubeSecretRepository.listByVendor(vendor.getId());
		Map<String, KubeSecret> secretMap = Maps.newHashMap();
		for (KubeSecret kubeSecret : listByVendor) {
			String key = kubeSecret.getUid();
			secretMap.put(key, kubeSecret);
		}
		for (SecretModel model : secretModels) {
			KubeSecret entity = new KubeSecret();
			String key = model.getUid();
			if (secretMap.containsKey(key)) {
				entity = secretMap.get(key);
				BeanUtils.copyProperties(model, entity);
				entity.setMenderId(userId);
				if (nsMap.containsKey(model.getNamespace())) {
					entity.setNsId(nsMap.get(model.getNamespace()).getId());
					entity.setAppId(nsMap.get(model.getNamespace()).getId());
					entity.setAppName(model.getNamespace());
				}
				Map<String, String> lablesMap = model.getLablesMap();
				if (null != lablesMap && lablesMap.containsKey("registryId")) {
					String registryId = lablesMap.get("registryId");
					entity.setHarborId(Long.parseLong(registryId));
				}
				kubeSecretRepository.update(entity);
				secretMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, entity);
			if (nsMap.containsKey(model.getNamespace())) {
				entity.setNsId(nsMap.get(model.getNamespace()).getId());
				entity.setAppId(nsMap.get(model.getNamespace()).getId());
				entity.setAppName(model.getNamespace());
			}
			Map<String, String> lablesMap = model.getLablesMap();
			if (null != lablesMap && lablesMap.containsKey("registryId")) {
				String registryId = lablesMap.get("registryId");
				entity.setHarborId(Long.parseLong(registryId));
			}
			entity.setCreatorId(userId);
			entity.setVendorId(vendor.getId());
			kubeSecretRepository.save(entity);
		}
		for (KubeSecret kubeSecret : secretMap.values()) {
			kubeSecretRepository.remove(kubeSecret.getId(), userId);
		}

	}

	private void syncPersistentVolumeClaimModels(List<PersistentVolumeClaimModel> persistentVolumeClaimModels,
			CloudVendor vendor, Long userId, Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(persistentVolumeClaimModels)) {
			persistentVolumeClaimRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubePersistentVolumeClaim> listByVendor = persistentVolumeClaimRepository.listByVendor(vendor.getId());
		Map<String, KubePersistentVolumeClaim> persistentVolumeMap = Maps.newHashMap();
		for (KubePersistentVolumeClaim persistentVolume : listByVendor) {
			String key = persistentVolume.getUid();
			persistentVolumeMap.put(key, persistentVolume);
		}
		for (PersistentVolumeClaimModel model : persistentVolumeClaimModels) {
			KubePersistentVolumeClaim entity = new KubePersistentVolumeClaim();
			String key = model.getUid();
			if (persistentVolumeMap.containsKey(key)) {
				entity = persistentVolumeMap.get(key);
				BeanUtils.copyProperties(model, entity);
				entity.setMenderId(userId);
				if (nsMap.containsKey(model.getNamespace())) {
					entity.setNsId(nsMap.get(model.getNamespace()).getId());
					entity.setAppId(nsMap.get(model.getNamespace()).getId());
					entity.setAppName(model.getNamespace());
				}
				persistentVolumeClaimRepository.update(entity);
				persistentVolumeMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, entity);
			if (nsMap.containsKey(model.getNamespace())) {
				entity.setNsId(nsMap.get(model.getNamespace()).getId());
				entity.setAppId(nsMap.get(model.getNamespace()).getId());
				entity.setAppName(model.getNamespace());
			}
			entity.setCreatorId(userId);
			entity.setVendorId(vendor.getId());
			persistentVolumeClaimRepository.save(entity);
		}
		for (KubePersistentVolumeClaim volume : persistentVolumeMap.values()) {
			persistentVolumeClaimRepository.remove(volume.getId(), userId);
		}

	}

	private void syncDaemonSetModel(List<DaemonSetModel> daemonSetModels, CloudVendor vendor, Long userId,
			Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(daemonSetModels)) {
			kubeDaemonSetRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeDaemonSet> kubeDaemonSetList = kubeDaemonSetRepository.listByVendor(vendor.getId());
		Map<String, KubeDaemonSet> daemonSetMap = Maps.newHashMap();
		for (KubeDaemonSet daemonSet : kubeDaemonSetList) {
			if (daemonSetMap.containsKey(daemonSet.getUid())) {
				kubeDaemonSetRepository.remove(daemonSet.getId(), userId);
			} else {
				daemonSetMap.put(daemonSet.getUid(), daemonSet);
			}
		}
		for (DaemonSetModel model : daemonSetModels) {
			KubeDaemonSet kubeDaemonSet = new KubeDaemonSet();
			String key = model.getUid();
			if (daemonSetMap.containsKey(key)) {
				kubeDaemonSet = daemonSetMap.get(key);
				BeanUtils.copyProperties(model, kubeDaemonSet);
				kubeDaemonSet.setMenderId(userId);
				kubeDaemonSet.setPodCount(model.getPodCount() == null ? 0 : model.getPodCount());
				if (nsMap.containsKey(model.getNamespace())) {
					kubeDaemonSet.setNsId(nsMap.get(model.getNamespace()).getId());
					kubeDaemonSet.setAppId(nsMap.get(model.getNamespace()).getId());
					kubeDaemonSet.setAppName(model.getNamespace());
				}
				kubeDaemonSetRepository.update(kubeDaemonSet);
				daemonSetMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, kubeDaemonSet);
			kubeDaemonSet.setCreatorId(userId);
			kubeDaemonSet.setPodCount(model.getPodCount() == null ? 0 : model.getPodCount());
			kubeDaemonSet.setTenantId(0L);
			kubeDaemonSet.setProjectId(0L);
			if (nsMap.containsKey(model.getNamespace())) {
				kubeDaemonSet.setNsId(nsMap.get(model.getNamespace()).getId());
				kubeDaemonSet.setAppId(nsMap.get(model.getNamespace()).getId());
				kubeDaemonSet.setAppName(model.getNamespace());
			}
			kubeDaemonSet.setVendorId(vendor.getId());
			kubeDaemonSetRepository.save(kubeDaemonSet);
		}
		for (KubeDaemonSet daemonSet : daemonSetMap.values()) {
			kubeDaemonSetRepository.remove(daemonSet.getId(), userId);
		}

	}

	private void syncPersistentModels(List<PersistentVolumeModel> persistentModels, CloudVendor vendor, Long userId,
			Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(persistentModels)) {
			persistentVolumeRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubePersistentVolume> persistentVolumeList = persistentVolumeRepository.listByVendor(vendor.getId());
		Map<String, KubePersistentVolume> persistentVolumeMap = Maps.newHashMap();
		for (KubePersistentVolume persistentVolume : persistentVolumeList) {
			String key = persistentVolume.getUid();
			persistentVolumeMap.put(key, persistentVolume);
		}
		for (PersistentVolumeModel model : persistentModels) {
			KubePersistentVolume entity = new KubePersistentVolume();
			String key = model.getUid();
			if (persistentVolumeMap.containsKey(key)) {
				entity = persistentVolumeMap.get(key);
				BeanUtils.copyProperties(model, entity);
				entity.setMenderId(userId);
				persistentVolumeRepository.update(entity);
				persistentVolumeMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, entity);
			entity.setCreatorId(userId);
			entity.setVendorId(vendor.getId());
			persistentVolumeRepository.save(entity);
		}
		for (KubePersistentVolume volume : persistentVolumeMap.values()) {
			persistentVolumeRepository.remove(volume.getId(), userId);
		}

	}

	private void syncDeployment(List<DeploymentModel> deploymentModels, CloudVendor vendor, Long userId,
			Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(deploymentModels)) {
			kubeDeploymentRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeDeployment> deploymentList = kubeDeploymentRepository.listByVendor(vendor.getId());
		Map<String, KubeDeployment> deploymentMap = Maps.newHashMap();
		for (KubeDeployment deployment : deploymentList) {
			if (deploymentMap.containsKey(deployment.getUid())) {
				kubeDeploymentRepository.remove(deployment.getId(), userId);
			} else {
				deploymentMap.put(deployment.getUid(), deployment);
			}
		}
		for (DeploymentModel model : deploymentModels) {
			KubeDeployment deployment = new KubeDeployment();
			String key = model.getUid();
			if (deploymentMap.containsKey(key)) {
				deployment = deploymentMap.get(key);
				BeanUtils.copyProperties(model, deployment);
				deployment.setMenderId(userId);
				deployment.setPodCount(model.getPodCount() == null ? 0 : model.getPodCount());
				if (nsMap.containsKey(model.getNamespace())) {
					deployment.setNsId(nsMap.get(model.getNamespace()).getId());
					deployment.setAppId(nsMap.get(model.getNamespace()).getId());
					deployment.setAppName(model.getNamespace());
				}
				kubeDeploymentRepository.update(deployment);
				deploymentMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, deployment);
			deployment.setPodCount(model.getPodCount() == null ? 0 : model.getPodCount());
			deployment.setCreatorId(userId);
			deployment.setTenantId(0L);
			deployment.setProjectId(0L);
			if (nsMap.containsKey(model.getNamespace())) {
				deployment.setNsId(nsMap.get(model.getNamespace()).getId());
				deployment.setAppId(nsMap.get(model.getNamespace()).getId());
				deployment.setAppName(model.getNamespace());
			}
			deployment.setVendorId(vendor.getId());
			kubeDeploymentRepository.save(deployment);
		}
		for (KubeDeployment deployment : deploymentMap.values()) {
			kubeDeploymentRepository.remove(deployment.getId(), userId);
		}
	}

	private void syncNamespace(List<NamespaceModel> namespaceModels, CloudVendor vendor, Long userId) throws Exception {
		if (ListTool.isEmpty(namespaceModels)) {
			namespaceRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeNamespace> nsList = namespaceRepository.listByVendor(vendor.getId());
		Map<String, KubeNamespace> nsMap = Maps.newHashMap();
		for (KubeNamespace namespace : nsList) {
			if (nsMap.containsKey(namespace.getUid())) {
				namespaceRepository.remove(namespace.getId(), userId);
			} else {
				nsMap.put(namespace.getUid(), namespace);
			}
		}
		for (NamespaceModel model : namespaceModels) {
			KubeNamespace namespace = new KubeNamespace();
			String key = model.getUid();
			if (nsMap.containsKey(key)) {
				namespace = nsMap.get(key);
				BeanUtils.copyProperties(model, namespace);
				namespace.setMenderId(userId);
				namespaceRepository.update(namespace);
				nsMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, namespace);
			namespace.setCreatorId(userId);
			namespace.setVendorId(vendor.getId());
			namespaceRepository.save(namespace);
		}
		for (KubeNamespace namespace : nsMap.values()) {
			namespaceRepository.remove(namespace.getId(), userId);
		}
	}

	private void syncNode(List<NodeModel> nodeModels, CloudVendor vendor, Long userId) throws Exception {
		if (ListTool.isEmpty(nodeModels)) {
			nodeRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeNode> nodes = nodeRepository.listByVendor(vendor.getId());
		Map<String, KubeNode> nodeMap = Maps.newHashMap();
		for (KubeNode node : nodes) {
			if (nodeMap.containsKey(node.getUid())) {
				namespaceRepository.remove(node.getId(), userId);
			} else {
				nodeMap.put(node.getUid(), node);
			}
		}
		for (NodeModel model : nodeModels) {
			KubeNode node = new KubeNode();
			String key = model.getUid();
			if (nodeMap.containsKey(key)) {
				node = nodeMap.get(key);
				BeanUtils.copyProperties(model, node);
				node.setMenderId(userId);
				nodeRepository.update(node);
				nodeMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, node);
			node.setCreatorId(userId);
			node.setVendorId(vendor.getId());
			nodeRepository.save(node);
		}
		for (KubeNode node : nodeMap.values()) {
			nodeRepository.remove(node.getId(), userId);
		}
	}

	private void syncService(List<ServiceModel> serviceModels, CloudVendor vendor, Long userId,
			Map<String, KubeNamespace> nsMap) throws Exception {
		if (ListTool.isEmpty(serviceModels)) {
			serviceRepository.removeByVendor(vendor.getId(), userId);
			return;
		}
		List<KubeService> services = serviceRepository.listByVendor(vendor.getId());
		Map<String, KubeService> serviceMap = Maps.newHashMap();
		for (KubeService service : services) {
			if (serviceMap.containsKey(service.getUid())) {
				serviceRepository.remove(service.getId(), userId);
			} else {
				serviceMap.put(service.getUid(), service);
			}
		}
		for (ServiceModel model : serviceModels) {
			KubeService service = new KubeService();
			String key = model.getUid();
			if (serviceMap.containsKey(key)) {
				service = serviceMap.get(key);
				BeanUtils.copyProperties(model, service);
				service.setMenderId(userId);
				if (null != model.getSelectorMap()) {
					service.setSelector(JSON.toJSONString(model.getSelectorMap()));
				}
				if (nsMap.containsKey(model.getNamespace())) {
					service.setNsId(nsMap.get(model.getNamespace()).getId());
				}
				serviceRepository.update(service);
				serviceMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, service);
			if (null != model.getSelectorMap()) {
				service.setSelector(JSON.toJSONString(model.getSelectorMap()));
			}
			if (nsMap.containsKey(model.getNamespace())) {
				service.setNsId(nsMap.get(model.getNamespace()).getId());
			}
			service.setTenantId(0L);
			service.setProjectId(0L);
			service.setCreatorId(userId);
			service.setVendorId(vendor.getId());
			serviceRepository.save(service);
		}
		for (KubeService service : serviceMap.values()) {
			serviceRepository.remove(service.getId(), userId);
		}
	}

	private void syncPod(List<PodModel> podModels, CloudVendor vendor, Long userId, Map<String, KubeNamespace> nsMap,
			Map<String, KubeNode> nodeMap, Map<String, KubeService> serviceMap) throws Exception {
		if (ListTool.isEmpty(podModels)) {
			podRepository.removeByVendor(vendor.getId(), userId);
			kubeContainerRepository.remove(vendor.getId(), null, userId);
			return;
		}
		List<KubePod> pods = podRepository.listByVendor(vendor.getId());
		Map<String, KubePod> podMap = Maps.newHashMap();
		for (KubePod kubePod : pods) {
			String key = kubePod.getUid();
			if (podMap.containsKey(key)) {
				podRepository.remove(kubePod.getId(), userId);
				kubeContainerRepository.remove(vendor.getId(), kubePod.getId(), userId);
			} else {
				podMap.put(key, kubePod);
			}
		}
		for (PodModel model : podModels) {
			KubePod pod = new KubePod();
			String key = model.getUid();
			if (podMap.containsKey(key)) {
				pod = podMap.get(key);
				BeanUtils.copyProperties(model, pod);
				pod.setMenderId(userId);
				if (nsMap.containsKey(model.getNamespace())) {
					pod.setNsId(nsMap.get(model.getNamespace()).getId());
				}
				if (nodeMap.containsKey(model.getNodeName())) {
					pod.setNodeId(nodeMap.get(model.getNodeName()).getId());
				}
				if (serviceMap.containsKey(model.getServiceName() + model.getNamespace())) {
					pod.setServiceId(serviceMap.get(model.getServiceName() + model.getNamespace()).getId());
				}
				if (null != model.getDeploymentName()) {
					List<Param> params = new ArrayList<Param>();
					params.add(new Param(MapTools.simpleMap("vendor_id", vendor.getId()), Sign.EQ));
					params.add(new Param(MapTools.simpleMap("ns_name", model.getNamespace()), Sign.EQ));
					params.add(new Param(MapTools.simpleMap("name", model.getDeploymentName()), Sign.EQ));
					List<KubeDeployment> list = kubeDeploymentRepository.list(1, 1, params, null);
					if (null != list && list.size() > 0) {
						pod.setTenantId(list.get(0).getTenantId());
						pod.setProjectId(list.get(0).getProjectId());
					}
				}
				podRepository.update(pod);
				this.syncContainers(model.getKubeContainers(), pod, vendor, userId);
				podMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, pod);
			pod.setCreatorId(userId);
			pod.setVendorId(vendor.getId());
			if (nsMap.containsKey(model.getNamespace())) {
				pod.setNsId(nsMap.get(model.getNamespace()).getId());
			}
			if (nodeMap.containsKey(model.getNodeName())) {
				pod.setNodeId(nodeMap.get(model.getNodeName()).getId());
			}
			if (serviceMap.containsKey(model.getServiceName() + model.getNamespace())) {
				pod.setServiceId(serviceMap.get(model.getServiceName() + model.getNamespace()).getId());
			}
			if (null != model.getDeploymentName()) {
				List<Param> params = new ArrayList<Param>();
				params.add(new Param(MapTools.simpleMap("vendor_id", vendor.getId()), Sign.EQ));
				params.add(new Param(MapTools.simpleMap("ns_name", model.getNamespace()), Sign.EQ));
				params.add(new Param(MapTools.simpleMap("name", model.getDeploymentName()), Sign.EQ));
				List<KubeDeployment> list = kubeDeploymentRepository.list(1, 1, params, null);
				if (null != list && list.size() > 0) {
					pod.setTenantId(list.get(0).getTenantId());
					pod.setProjectId(list.get(0).getProjectId());
				}
			}
			podRepository.save(pod);
			this.syncContainers(model.getKubeContainers(), pod, vendor, userId);
		}
		for (KubePod pod : podMap.values()) {
			podRepository.remove(pod.getId(), userId);
			kubeContainerRepository.remove(vendor.getId(), pod.getId(), userId);
		}
	}

	private void syncContainers(List<ContainerModel> kubeContainerModels, KubePod pod, CloudVendor vendor, Long userId)
			throws Exception {
		if (ListTool.isEmpty(kubeContainerModels)) {
			kubeContainerRepository.remove(vendor.getId(), pod.getId(), userId);
			return;
		}
		List<KubeContainer> kubeContainers = kubeContainerRepository.listByVendor(vendor.getId(), pod.getId());
		Map<String, KubeContainer> kubeContainerMap = Maps.newHashMap();
		for (KubeContainer kubeContainer : kubeContainers) {
			String key = kubeContainer.getContainerId();
			if (kubeContainerMap.containsKey(key)) {
				kubeContainerRepository.remove(vendor.getId(), pod.getId(), userId);
			} else {
				kubeContainerMap.put(key, kubeContainer);
			}
		}
		for (ContainerModel containerModel : kubeContainerModels) {
			KubeContainer kubeContainer = new KubeContainer();
			String key = containerModel.getContainerId();
			if (kubeContainerMap.containsKey(key)) {
				kubeContainer = kubeContainerMap.get(key);
				BeanUtils.copyProperties(containerModel, kubeContainer);
				kubeContainer.setMenderId(userId);
				kubeContainer.setCreatorId(userId);
				kubeContainer.setVendorId(pod.getVendorId());
				kubeContainer.setNsId(pod.getNsId());
				kubeContainer.setNamespace(pod.getNamespace());
				kubeContainer.setNodeId(pod.getNodeId());
				kubeContainer.setNodeName(pod.getNodeName());
				kubeContainer.setServiceId(pod.getServiceId());
				kubeContainer.setServiceName(pod.getServiceName());
				kubeContainer.setPodId(pod.getId());
				kubeContainer.setPodName(pod.getName());
				kubeContainerRepository.update(kubeContainer);
				kubeContainerMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(containerModel, kubeContainer);
			kubeContainer.setMenderId(userId);
			kubeContainer.setCreatorId(userId);
			kubeContainer.setVendorId(pod.getVendorId());
			kubeContainer.setNsId(pod.getNsId());
			kubeContainer.setNamespace(pod.getNamespace());
			kubeContainer.setNodeId(pod.getNodeId());
			kubeContainer.setNodeName(pod.getNodeName());
			kubeContainer.setServiceId(pod.getServiceId());
			kubeContainer.setServiceName(pod.getServiceName());
			kubeContainer.setPodId(pod.getId());
			kubeContainer.setPodName(pod.getName());
			kubeContainerRepository.save(kubeContainer);
		}
		for (KubeContainer kubeContainer : kubeContainerMap.values()) {
			kubeContainerRepository.remove(kubeContainer.getId(), userId);
		}

	}

}
