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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.kubernetes.DeploymentDriver;
import com.bocloud.cmp.model.NotifyMessage;
import com.bocloud.cmp.model.kubernetes.ContainerModel;
import com.bocloud.cmp.model.kubernetes.DeploymentModel;
import com.bocloud.cmp.model.kubernetes.KubeDeploymentParam;
import com.bocloud.cmp.model.kubernetes.PodModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
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.KubeDeployment;
import com.bocloud.ims.entity.resource.kubernetes.KubeNamespace;
import com.bocloud.ims.entity.resource.kubernetes.KubeNode;
import com.bocloud.ims.entity.resource.kubernetes.KubePod;
import com.bocloud.ims.entity.resource.kubernetes.KubeService;
import com.bocloud.ims.interfaces.resource.kubernetes.KubeDeploymentService;
import com.bocloud.ims.interfaces.resource.kubernetes.KubePodService;
import com.bocloud.ims.repository.kubernetes.KubeContainerRepository;
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.KubePodRepository;
import com.bocloud.ims.repository.kubernetes.KubeServiceRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Maps;

@Service("kubeDeploymentService")
public class KubeDeploymentServiceImpl implements KubeDeploymentService {

	private static final Logger logger = LoggerFactory.getLogger(KubeDeploymentServiceImpl.class);
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private KubeDeploymentRepository kubeDeploymentRepository;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private DeploymentDriver deploymentDriver;
	@Autowired
	private KubeNamespaceRepository namespaceRepository;
	@Autowired
	private KubePodRepository kubePodRepository;
	@Autowired
	private KubeServiceRepository kubeServiceRepository;
	@Autowired
	private KubeNodeRepository kubeNodeRepository;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private KubeContainerRepository kubeContainerRepository;
	@Autowired
	private KubePodService kubePodService;

	@Override
	public BocloudResult list(Pager pager, RequestContext context) {
		GridBean gridBean = null;
		try {

			List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
			Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
			Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
			sorter.put("gmtCreate", Common.ONE);
			Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
			Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);

			int total = 0;
			Long tenantId = context.getTenant();
			// 为租户下的用户
			List<KubeDeployment> list = null;
			if (null != tenantId && 0L != tenantId) {
				total = this.kubeDeploymentRepository.count(params, null);
				list = this.kubeDeploymentRepository.list(page, rows, params, sorter, null);
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = this.kubeDeploymentRepository.count(params);
				if (simple) {
					List<SimpleBean> beans = this.kubeDeploymentRepository.list(params, sorter);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = this.kubeDeploymentRepository.list(page, rows, params, sorter);
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query KubeDeployment list fail:", e);
			return new BocloudResult(false, "查询失败");
		}
	}

	@Override
	public BocloudResult create(KubeDeployment deployment, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(deployment.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			String yamlText = deployment.getYamlText();
			if (StringUtils.isEmpty(yamlText)) {
				return new BocloudResult(false, "参数格式错误！");
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					BocloudResult bocloudResult = new BocloudResult(false, "创建部署失败！");
					try {
						DeploymentModel model = new DeploymentModel();
						BeanUtils.copyProperties(deployment, model);
						bocloudResult = deploymentDriver.create(vendor.getUuid(), model);
						if (bocloudResult.isSuccess()) {
							DeploymentModel deploymentModel = (DeploymentModel) bocloudResult.getData();
							BeanUtils.copyProperties(deploymentModel, deployment);
							deployment.setCreatorId(context.getTarget());
							deployment.setMenderId(context.getTarget());
							deployment.setVendorId(vendor.getId());
							if (StringUtils.isEmpty(deploymentModel.getNamespace())) {
								KubeNamespace kubeNamespace = namespaceRepository
										.queryByName(deploymentModel.getNamespace(), vendor.getId());
								if (null != kubeNamespace) {
									deployment.setNsId(kubeNamespace.getId());
								}
							}
							kubeDeploymentRepository.save(deployment);
							List<PodModel> podModels = deploymentModel.getPodModels();
							if (null != podModels && !podModels.isEmpty()) {
								KubePod pod = null;
								for (PodModel createModel : podModels) {
									pod = new KubePod();
									BeanUtils.copyProperties(createModel, pod);
									pod.setCreatorId(context.getTarget());
									pod.setDeploymentName(deployment.getName());
									pod.setMenderId(context.getTarget());
									pod.setVendorId(vendor.getId());
									if (StringUtils.isEmpty(createModel.getNamespace())) {
										KubeNamespace kubeNamespace = namespaceRepository
												.queryByName(createModel.getNamespace(), vendor.getId());
										if (null != kubeNamespace) {
											pod.setNsId(kubeNamespace.getId());
										}
									}
									if (StringUtils.isEmpty(createModel.getNodeName())) {
										KubeNode node = kubeNodeRepository.querByName(createModel.getNodeName(),
												vendor.getId());
										if (null != node) {
											pod.setNodeId(node.getId());
										}
									}
									if (StringUtils.isEmpty(createModel.getServiceName())) {
										KubeService service = kubeServiceRepository
												.querByName(createModel.getServiceName(), vendor.getId());
										if (null != service) {
											pod.setServiceId(service.getId());
										}
									}
									kubePodRepository.save(pod);
									kubePodService.syncContainers(createModel.getKubeContainers(), pod, vendor,
											context);
								}
							}
							// 发送给云平台统计队列对云平台重新统计
							JSONObject jsonObject = new JSONObject();
							jsonObject.put(Common.VENDORID, vendor.getId());
							amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
						}
					} catch (Exception e) {
						logger.info("创建部署异常：" + e.getMessage());
						bocloudResult.setMessage(e.getMessage());
					}
					resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), bocloudResult.getMessage(),
							"kubernetes.service", MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult(true, "创建部署任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("create deployment error", e);
			return new BocloudResult(false, "添加失败");
		}
	}

	@Override
	public BocloudResult modify(KubeDeployment deployment, RequestContext context) {
		String path = KubeDeployment.class.getSimpleName() + "_" + deployment.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubeDeployment object = this.kubeDeploymentRepository.query(deployment.getId());
			if (null == object) {
				logger.warn("deployment does not exist!");
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(object.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			String yamlText = deployment.getYamlText();
			if (StringUtils.isEmpty(yamlText)) {
				return new BocloudResult(false, "参数格式错误！");
			}
			JSONObject parseObject = JSONObject.parseObject(yamlText, JSONObject.class);
			JSONObject jsonObject = parseObject.getJSONObject("metadata");
			String newName = jsonObject.getString("name");
			String namespace = jsonObject.getString("namespace");
			if (!object.getName().equals(newName) || !object.getNamespace().equals(namespace)) {
				return new BocloudResult(false, "服务命名空间/名称不允许修改！");
			}
			DeploymentModel model = new DeploymentModel();
			BeanUtils.copyProperties(deployment, model);
			BocloudResult bocloudResult = deploymentDriver.modify(vendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return new BocloudResult(false, bocloudResult.getMessage());
			}
			DeploymentModel createModel = (DeploymentModel) bocloudResult.getData();
			BeanUtils.copyProperties(createModel, object);
			this.kubeDeploymentRepository.update(object);
			return new BocloudResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify deployment fail:", e);
			return new BocloudResult(false, "修改失败");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = KubeDeployment.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubeDeployment deployment = this.kubeDeploymentRepository.query(id);
			if (null == deployment) {
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(deployment.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						DeploymentModel model = new DeploymentModel();
						BeanUtils.copyProperties(deployment, model);
						BocloudResult bocloudResult = deploymentDriver.remove(model, vendor.getUuid());
						if (bocloudResult.isSuccess()) {
							kubeDeploymentRepository.remove(id, context.getTarget());
							// 删除部署成功后 删除对应pod
							List<Param> params = new ArrayList<Param>();
							params.add(new Param(MapTools.simpleMap("deployment_uid", deployment.getUid()), Sign.EQ));
							params.add(new Param(MapTools.simpleMap("vendor_id", deployment.getVendorId()), Sign.EQ));
							params.add(new Param(MapTools.simpleMap("ns_name", deployment.getNamespace()), Sign.EQ));
							List<KubePod> kubePods = kubePodRepository.listByParams(params);
							if (null != kubePods && !kubePods.isEmpty()) {
								for (KubePod kubePod : kubePods) {
									kubePodRepository.remove(kubePod.getId(), context.getTarget());
									kubeContainerRepository.remove(vendor.getId(), kubePod.getId(),
											context.getTarget());
								}
							}
							// 发送给云平台统计队列对云平台重新统计
							JSONObject jsonObject = new JSONObject();
							jsonObject.put(Common.VENDORID, vendor.getId());
							amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
						}

						resourceEventPublisher
								.send(new OperateResult(bocloudResult.isSuccess(), bocloudResult.getMessage(),
										"kubernetes.service", MapTools.simpleMap(Common.VENDORID, vendor.getId()),
										OperateResult.OperateCategory.ResourceEvent, context));

					} catch (Exception e) {
						logger.error("删除部署失败：" + e.getMessage());
						resourceEventPublisher.send(new OperateResult(false, "删除Deployment失败：" + e.getMessage(),
								"kubernetes.service", MapTools.simpleMap(Common.VENDORID, vendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				}
			}).start();
			return new BocloudResult(true, "任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("Remove deployment error:", e);
			return new BocloudResult(false, "删除失败");
		}
	}

	@Override
	public BocloudResult detail(Long id) {
		try {
			KubeDeployment deployment = this.kubeDeploymentRepository.query(id);
			if (null == deployment) {
				return new BocloudResult(false, "数据不存在");
			}
			return new BocloudResult(true, deployment, "查询详情成功");
		} catch (Exception e) {
			logger.error("Get deployment error：", e);
			return new BocloudResult(false, "查询详情失败");
		}
	}

	@Override
	public BocloudResult apply(String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			if (null == object) {
				return new BocloudResult(false, "参数格式错误！");
			}
			Long vendorId = object.getLong(Common.VENDORID);
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult(false, "云平台不存在！");
			}
			String yamlText = object.getString("yamlText");
			if (StringUtils.isEmpty(yamlText)) {
				return new BocloudResult(false, "参数格式错误！");
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					BocloudResult bocloudResult = new BocloudResult(false, "部署申请失败！");
					try {
						DeploymentModel model = new DeploymentModel();
						model.setYamlText(yamlText);
						bocloudResult = deploymentDriver.create(vendor.getUuid(), model);
						if (bocloudResult.isSuccess()) {
							DeploymentModel deploymentModel = (DeploymentModel) bocloudResult.getData();
							KubeDeployment deployment = new KubeDeployment();
							BeanUtils.copyProperties(deploymentModel, deployment);
							deployment.setCreatorId(context.getTarget());
							deployment.setMenderId(context.getTarget());
							deployment.setVendorId(vendor.getId());
							deployment.setTenantId(context.getTenant());
							if (StringUtils.isEmpty(deploymentModel.getNamespace())) {
								KubeNamespace kubeNamespace = namespaceRepository
										.queryByName(deploymentModel.getNamespace(), vendor.getId());
								if (null != kubeNamespace) {
									deployment.setNsId(kubeNamespace.getId());
								}
							}
							kubeDeploymentRepository.save(deployment);
							bocloudResult.setMessage("K8S部署申请成功！部署名称：【" + deployment.getName() + "】");
							List<PodModel> podModels = deploymentModel.getPodModels();
							if (null != podModels && !podModels.isEmpty()) {
								KubePod pod = null;
								for (PodModel createModel : podModels) {
									pod = new KubePod();
									BeanUtils.copyProperties(createModel, pod);
									pod.setCreatorId(context.getTarget());
									pod.setDeploymentName(deployment.getName());
									pod.setMenderId(context.getTarget());
									pod.setVendorId(vendor.getId());
									pod.setTenantId(context.getTenant());
									if (StringUtils.isEmpty(createModel.getNamespace())) {
										KubeNamespace kubeNamespace = namespaceRepository
												.queryByName(createModel.getNamespace(), vendor.getId());
										if (null != kubeNamespace) {
											pod.setNsId(kubeNamespace.getId());
										}
									}
									if (StringUtils.isEmpty(createModel.getNodeName())) {
										KubeNode node = kubeNodeRepository.querByName(createModel.getNodeName(),
												vendor.getId());
										if (null != node) {
											pod.setNodeId(node.getId());
										}
									}
									if (StringUtils.isEmpty(createModel.getServiceName())) {
										KubeService service = kubeServiceRepository
												.querByName(createModel.getServiceName(), vendor.getId());
										if (null != service) {
											pod.setServiceId(service.getId());
										}
									}
									kubePodRepository.save(pod);
								}
							}
						}
					} catch (Exception e) {
						logger.error("Kubernetes部署申请失败：" + e.getMessage());
						bocloudResult.setMessage("Kubernetes部署申请失败：" + e.getMessage());
					}
					// 站内信
					NotifyMessage message = new NotifyMessage(context, "K8S部署申请", bocloudResult.getMessage(), true,
							true);
					amqpTemplate.convertAndSend("event.notice.queue", message);
					resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), bocloudResult.getMessage(),
							"kubernetes.service", MapTools.simpleMap(Common.VENDORID, vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
				}
			}).start();
			return new BocloudResult(true, "Kubernetes部署申请任务已下发...正在执行！");
		} catch (Exception e) {
			logger.error("Get service error：", e);
			return new BocloudResult(false, e.getMessage());
		}
	}

	public Long getVCpu(String maxCpu) {
		Long cpu = 0L;
		if (StringUtils.isEmpty(maxCpu)) {
			return cpu;
		}
		if (maxCpu.contains("m")) {
			maxCpu = maxCpu.substring(0, maxCpu.indexOf("m"));
			cpu = Long.parseLong(maxCpu);
		} else {
			cpu = Long.parseLong(maxCpu) * 1000;
		}
		return cpu;
	}

	public Long getVMem(String maxMem) {
		Long mem = 0L;
		if (StringUtils.isEmpty(maxMem)) {
			return mem;
		}
		if (maxMem.contains("M")) {
			maxMem = maxMem.substring(0, maxMem.indexOf("M"));
			mem = Long.parseLong(maxMem);
		} else if (maxMem.contains("G")) {
			maxMem = maxMem.substring(0, maxMem.indexOf("G"));
			mem = Long.parseLong(maxMem) * 1024;
		} else {
			mem = Long.parseLong(maxMem);
		}
		return mem;
	}

	@Override
	public BocloudResult extendReplicas(KubeDeploymentParam kubeDeploymentParam, RequestContext context) {
		try {
			if (null == kubeDeploymentParam) {
				return new BocloudResult(false, "参数格式错误！");
			}
			Long id = kubeDeploymentParam.getId();
			KubeDeployment kubeDeployment = kubeDeploymentRepository.query(id);
			if (null == kubeDeployment) {
				return new BocloudResult(false, "资源不存在！");
			}
			KubeNamespace kubeNamespace = namespaceRepository.query(kubeDeployment.getNsId());
			if (null == kubeNamespace) {
				logger.error("应用不存在！");
				return new BocloudResult(false, "扩容缩容异常！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(kubeDeployment.getVendorId());
			if (null == cloudVendor) {
				return new BocloudResult(false, "集群信息异常！");
			}
			Integer replica = kubeDeploymentParam.getReplica();
			if (null == replica || replica < 1) {
				return new BocloudResult(false, "不支持的实例数！");
			}
			Integer oldReplica = kubeDeployment.getReplica();
			Integer newReplica = replica - oldReplica;
			if (newReplica > 0) {
				// 配额
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						DeploymentModel model = new DeploymentModel();
						model.setName(kubeDeployment.getName());
						model.setNamespace(kubeDeployment.getNamespace());
						model.setReplica(replica);
						BocloudResult bocloudResult = deploymentDriver.extendReplicas(cloudVendor.getUuid(), model);
						if (bocloudResult.isFailed()) {
							resourceEventPublisher.send(new OperateResult(false, bocloudResult.getMessage(),
									"kubernetes.service", MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
									OperateResult.OperateCategory.ResourceEvent, context));
							return;
						}
						DeploymentModel deploymentModel = (DeploymentModel) bocloudResult.getData();
						kubeDeployment.setReplica(replica);
						kubeDeployment.setPodCount(deploymentModel.getPodCount());
						kubeDeploymentRepository.update(kubeDeployment);
						List<PodModel> podModels = deploymentModel.getPodModels();
						if (null != podModels && !podModels.isEmpty()) {
							syncPod(podModels, cloudVendor, context, kubeDeployment);
						}
						// 发送给云平台统计队列对云平台重新统计
						JSONObject jsonObject = new JSONObject();
						jsonObject.put(Common.VENDORID, cloudVendor.getId());
						amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
						resourceEventPublisher.send(new OperateResult(bocloudResult.isSuccess(), "扩容/缩容成功！",
								"kubernetes.service", MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));

					} catch (Exception e) {
						logger.error("扩容缩容异常：" + e.getMessage());
						resourceEventPublisher.send(new OperateResult(false, "扩容缩容异常：" + e.getMessage(),
								"kubernetes.service", MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				}
			}).start();
			return new BocloudResult(true, "任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("Get deployment error：", e);
			return new BocloudResult(false, "查询详情失败");
		}
	}

	private void syncPod(List<PodModel> podModels, CloudVendor vendor, RequestContext context,
			KubeDeployment kubeDeployment) throws Exception {
		if (ListTool.isEmpty(podModels)) {
			return;
		}
		List<Param> queryParams = new ArrayList<>();
		queryParams.add(new Param(MapTools.simpleMap("deployment_uid", kubeDeployment.getUid()), Sign.EQ));
		queryParams.add(new Param(MapTools.simpleMap("vendor_id", kubeDeployment.getVendorId()), Sign.EQ));
		queryParams.add(new Param(MapTools.simpleMap("ns_name", kubeDeployment.getNamespace()), Sign.EQ));
		List<KubePod> pods = kubePodRepository.listByParams(queryParams);
		Map<String, KubePod> podMap = Maps.newHashMap();
		for (KubePod kubePod : pods) {
			String key = kubePod.getUid();
			if (podMap.containsKey(key)) {
				kubePodRepository.remove(kubePod.getId(), context.getTarget());
				kubeContainerRepository.remove(vendor.getId(), kubePod.getId(), context.getTarget());
			} 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(context.getTarget());
				pod.setNsId(kubeDeployment.getNsId());
				if (!StringUtils.isEmpty(model.getNodeName())) {
					KubeNode node = kubeNodeRepository.querByName(model.getNodeName(), vendor.getId());
					if (null != node) {
						pod.setNodeId(node.getId());
					}
				}
				if (!StringUtils.isEmpty(model.getServiceName())) {
					KubeService service = kubeServiceRepository.querByName(model.getServiceName(), vendor.getId());
					if (null != service) {
						pod.setServiceId(service.getId());
					}
				}
				pod.setTenantId(kubeDeployment.getTenantId());
				kubePodRepository.update(pod);
				this.syncContainers(model.getKubeContainers(), pod, vendor, context);
				podMap.remove(key);
				continue;
			}
			BeanUtils.copyProperties(model, pod);
			pod.setCreatorId(context.getTarget());
			pod.setVendorId(vendor.getId());
			pod.setNsId(kubeDeployment.getNsId());
			if (!StringUtils.isEmpty(model.getNodeName())) {
				KubeNode node = kubeNodeRepository.querByName(model.getNodeName(), vendor.getId());
				if (null != node) {
					pod.setNodeId(node.getId());
				}
			}
			if (!StringUtils.isEmpty(model.getServiceName())) {
				KubeService service = kubeServiceRepository.querByName(model.getServiceName(), vendor.getId());
				if (null != service) {
					pod.setServiceId(service.getId());
				}
			}
			pod.setTenantId(kubeDeployment.getTenantId());
			kubePodRepository.save(pod);
			this.syncContainers(model.getKubeContainers(), pod, vendor, context);
		}
		for (KubePod pod : podMap.values()) {
			kubePodRepository.remove(pod.getId(), context.getTarget());
			kubeContainerRepository.remove(vendor.getId(), pod.getId(), context.getTarget());
		}
	}

	private void syncContainers(List<ContainerModel> kubeContainerModels, KubePod pod, CloudVendor vendor,
			RequestContext context) throws Exception {
		if (ListTool.isEmpty(kubeContainerModels)) {
			kubeContainerRepository.remove(vendor.getId(), pod.getId(), context.getTarget());
			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(), context.getTarget());
			} 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(context.getTarget());
				kubeContainer.setCreatorId(context.getTarget());
				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(context.getTarget());
			kubeContainer.setCreatorId(context.getTarget());
			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(), context.getTarget());
		}

	}

}
