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

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

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 org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.kubernetes.DaemonSetDriver;
import com.bocloud.cmp.driver.kubernetes.DeploymentDriver;
import com.bocloud.cmp.driver.kubernetes.NamespaceDriver;
import com.bocloud.cmp.driver.kubernetes.PodDriver;
import com.bocloud.cmp.model.kubernetes.DaemonSetModel;
import com.bocloud.cmp.model.kubernetes.DeploymentModel;
import com.bocloud.cmp.model.kubernetes.NamespaceModel;
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.Harbor;
import com.bocloud.ims.entity.resource.HarborImage;
import com.bocloud.ims.entity.resource.HarborProject;
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.KubePod;
import com.bocloud.ims.entity.resource.kubernetes.KubeSecret;
import com.bocloud.ims.entity.resource.kubernetes.KubeService;
import com.bocloud.ims.interfaces.resource.kubernetes.KubeNamespaceService;
import com.bocloud.ims.interfaces.resource.kubernetes.KubePodService;
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.KubePodRepository;
import com.bocloud.ims.repository.kubernetes.KubeSecretRepository;
import com.bocloud.ims.repository.kubernetes.KubeServiceRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.HarborImageRepository;
import com.bocloud.ims.repository.resource.HarborProjectRepository;
import com.bocloud.ims.repository.resource.HarborRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service("kubeNamespaceService")
public class KubeNamespaceServiceImpl implements KubeNamespaceService {

	private static final Logger logger = LoggerFactory.getLogger(KubeNamespaceServiceImpl.class);
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private KubeNamespaceRepository kubeNamespaceRepository;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private NamespaceDriver namespaceDriver;
	@Autowired
	private DeploymentDriver deploymentDriver;
	@Autowired
	private DaemonSetDriver daemonSetDriver;
	@Autowired
	private KubeDeploymentRepository kubeDeploymentRepository;
	@Autowired
	private KubePodRepository kubePodRepository;
	@Autowired
	private KubeServiceRepository kubeServiceRepository;
	@Autowired
	private KubeNodeRepository kubeNodeRepository;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private KubePodService kubePodService;
	@Autowired
	private KubeDaemonSetRepository kubeDaemonSetRepository;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private HarborImageRepository harborImageRepository;
	@Autowired
	private KubeSecretRepository kubeSecretRepository;
	@Autowired
	private KubeContainerRepository kubeContainerRepository;
	@Autowired
	private HarborProjectRepository harborProjectRepository;
	@Autowired
	private HarborRepository harborRepository;
	@Autowired
	private PodDriver podDriver;

	@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);

			Long tenantId = context.getTenant();
			Long userId = context.getTarget();
			int total = 0;
			List<KubeNamespace> list = new ArrayList<>();
			if (null != tenantId && 0L != tenantId) {
				total = this.kubeNamespaceRepository.count(params, tenantId, userId, null, null);
				list = this.kubeNamespaceRepository.list(page, rows, params, sorter, tenantId, userId, null, null);
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = this.kubeNamespaceRepository.count(params);
				if (simple) {
					List<SimpleBean> beans = this.kubeNamespaceRepository.list(params, sorter);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = this.kubeNamespaceRepository.list(page, rows, params, sorter);
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query namespace list fail:", e);
			return new BocloudResult(false, "查询失败");
		}
	}

	@Override
	public BocloudResult createServices(String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			if (null == object) {
				return new BocloudResult(false, "参数格式错误！");
			}
			Long namespaceId = object.getLong("namespaceId");
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(namespaceId);
			if (null == kubeNamespace) {
				return new BocloudResult(false, "所属应用异常！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(kubeNamespace.getVendorId());
			if (null == cloudVendor) {
				return new BocloudResult(false, "集群信息异常！");
			}
			String resources = object.getString("resources");
			if (StringUtils.isEmpty(resources)) {
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("maxCpu", kubeNamespace.getDefaultCpu());
				jsonObject.put("minCpu", kubeNamespace.getDefaultCpu());
				jsonObject.put("minMem", kubeNamespace.getDefaultMemory());
				jsonObject.put("maxMem", kubeNamespace.getDefaultMemory());
				object.put("resources", jsonObject);
			} else {
				// 资源配置中，request值应小于或等于limit值
				BocloudResult result = this.checkResource(resources);
				if (result.isFailed()) {
					return result;
				}
			}
			// Deployment DaemonSet
			String kind = object.getString("kind");
			JSONObject resourceObj = object.getJSONObject("resources");
			String maxCpu = resourceObj.getString("maxCpu");
			String maxMem = resourceObj.getString("maxMem");
			Integer replica = 0;
			switch (kind) {
			case KubeConstant.DEPLOYMENT:
				replica = object.getInteger("replica") == null ? 1 : object.getInteger("replica");
				break;
			case KubeConstant.DAEMONSET:
				// 暂时 逻辑 后续需要考虑亲和性
				List<KubeNode> listByVendor = kubeNodeRepository.listByVendor(kubeNamespace.getVendorId());
				if (!ListTool.isEmpty(listByVendor)) {
					replica = listByVendor.size();
				}
				break;
			default:
				break;
			}
			String imageName = "";
			String imageType = object.getString("imageType");
			KubeSecret kubeSecret = null;
			// 镜像tag
			String versionName = object.getString("imageVersion");
			if ("PUBLIC".equalsIgnoreCase(imageType)) {
				imageName = object.getString("imageName");
			} else {
				// 镜像名称 测试数据
				Long imageId = object.getLong("imageId");
				HarborImage harborImage = harborImageRepository.query(imageId);
				if (null == harborImage) {
					return new BocloudResult(false, "镜像不存在！");
				}
				imageName = harborImage.getName();
				HarborProject harborProject = harborProjectRepository.query(harborImage.getProjectId());
				if (null == harborProject) {
					logger.error("查询Harbor项目异常！！！");
					return new BocloudResult(false, "服务发布失败！");
				}
				if (!imageName.contains(harborProject.getName() + "/")) {
					imageName = harborProject.getName() + "/" + imageName;
				}
				Harbor harbor = harborRepository.query(harborProject.getHarborId());
				if (null == harbor) {
					logger.error("Harbor仓库异常！！！");
					return new BocloudResult(false, "服务发布失败！");
				}
				if (!imageName.contains(harbor.getServerIp() + "/")) {
					imageName = harbor.getServerIp() + "/" + imageName;
				}
				Long secretId = object.getLong("secretId");
				kubeSecret = kubeSecretRepository.query(secretId);
				if (null == kubeSecret) {
					return new BocloudResult(false, "Secret数据异常！");
				}
				object.put("secretName", kubeSecret.getName());
			}
			// 服务名称
			String name = object.getString("name");
			switch (kind) {
			case KubeConstant.DEPLOYMENT:
				KubeDeployment kubeDeployment = kubeDeploymentRepository.getByName(name, cloudVendor.getId());
				if (null != kubeDeployment) {
					return new BocloudResult(false, "服务名称已存在！");
				}
				break;
			case KubeConstant.DAEMONSET:
				KubeDaemonSet kubeDaemonSet = kubeDaemonSetRepository.getByName(name, cloudVendor.getId());
				if (null != kubeDaemonSet) {
					return new BocloudResult(false, "服务名称已存在！");
				}
				break;
			default:
				break;
			}
			String labels = object.getString("labels");
			Map<String, String> labelsMap = new HashMap<String, String>();
			labelsMap.put("kubernetes.customized/pod-affinity", name);
			labelsMap.put("applicationName", name);
			if (!StringUtils.isEmpty(labels)) {
				List<JSONObject> array = JSONObject.parseArray(labels, JSONObject.class);
				for (JSONObject jsonObject : array) {
					labelsMap.put(jsonObject.getString("key"), jsonObject.getString("value"));
				}
			}
			Map<String, String> selector = new HashMap<String, String>();
			selector.put("applicationName", name);
			if (!StringUtils.isEmpty(versionName)) {
				imageName = imageName + ":" + versionName;
				selector.put("versionName", versionName);
			}
			labelsMap.putAll(selector);
			logger.info("容器创建start : 云平台={} | 所属应用={} | 容器类型={} | 镜像：{}", cloudVendor.getName(),
					kubeNamespace.getName(), kind, imageName);
			final String podImageName = imageName;
			new Thread(new Runnable() {
				@Override
				public void run() {
					BocloudResult bocloudResult = new BocloudResult(false, "资源创建失败！");
					try {
						switch (kind) {
						case KubeConstant.DEPLOYMENT:
							DeploymentModel deploymentModel = JSON.parseObject(object.toJSONString(),
									DeploymentModel.class);
							deploymentModel.setNamespace(kubeNamespace.getName());
							deploymentModel.setLabelsMap(labelsMap);
							deploymentModel.setSelectorMap(selector);
							deploymentModel.setImage(podImageName);
							bocloudResult = createDeployment(deploymentModel, cloudVendor, kubeNamespace, context);
							break;
						case KubeConstant.DAEMONSET:
							DaemonSetModel daemonSetModel = JSON.parseObject(object.toJSONString(),
									DaemonSetModel.class);
							daemonSetModel.setNamespace(kubeNamespace.getName());
							daemonSetModel.setLabelsMap(labelsMap);
							daemonSetModel.setSelectorMap(selector);
							daemonSetModel.setImage(podImageName);
							bocloudResult = createDaemonSet(daemonSetModel, cloudVendor, kubeNamespace, context);
							break;
						default:
							break;
						}
						logger.info("容器创建结果：{} {}", bocloudResult.isSuccess(), bocloudResult.getMessage());
						resourceEventPublisher
								.send(new OperateResult(bocloudResult.isSuccess(), bocloudResult.getMessage(),
										"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("create application error", e);
			return new BocloudResult(false, "发布服务失败");
		}
	}

	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;
	}

	public BocloudResult checkCpu(String min, String max, String unit) {
		BocloudResult bocloudResult = new BocloudResult(false, "资源配置中，request值应小于或等于limit值");
		try {
			if (min.contains(unit) && max.contains(unit)) {
				min = min.substring(0, min.indexOf(unit));
				max = max.substring(0, max.indexOf(unit));
				if (Integer.valueOf(min) > Integer.valueOf(max)) {
					return bocloudResult;
				}
			}
			if (!min.contains(unit) && !max.contains(unit)) {
				if (Integer.valueOf(min) > Integer.valueOf(max)) {
					return bocloudResult;
				}
			}
			if (!min.contains(unit) && max.contains(unit)) {
				return bocloudResult;
			}
			return new BocloudResult(true, "资源校验成功！");
		} catch (Exception e) {
			return new BocloudResult(false, "资源校验失败！");
		}
	}

	private BocloudResult checkResource(String resources) {
		try {
			JSONObject parseObject = JSONObject.parseObject(resources);
			String minCpu = parseObject.getString("minCpu");
			String maxCpu = parseObject.getString("maxCpu");
			BocloudResult cpuCheck = checkCpu(minCpu, maxCpu, "m");
			if (cpuCheck.isFailed()) {
				return cpuCheck;
			}
			String minMem = parseObject.getString("minMem");
			String maxMem = parseObject.getString("maxMem");
			BocloudResult memCheck = checkMem(minMem, maxMem, null);
			if (memCheck.isFailed()) {
				return memCheck;
			}
			return new BocloudResult(true, "资源校验成功！");
		} catch (Exception e) {
			return new BocloudResult(false, "资源校验异常！");
		}
	}

	private BocloudResult checkMem(String minMem, String maxMem, String string) {
		BocloudResult bocloudResult = new BocloudResult(false, "资源配置中，request值应小于或等于limit值");
		try {
			if (minMem.contains("M") && maxMem.contains("M")) {
				minMem = minMem.substring(0, minMem.indexOf("M"));
				maxMem = maxMem.substring(0, maxMem.indexOf("M"));
				if (Integer.valueOf(minMem) > Integer.valueOf(maxMem)) {
					return bocloudResult;
				}
			}
			if (minMem.contains("G") && maxMem.contains("G")) {
				minMem = minMem.substring(0, minMem.indexOf("G"));
				maxMem = maxMem.substring(0, maxMem.indexOf("G"));
				if (Integer.valueOf(minMem) > Integer.valueOf(maxMem)) {
					return bocloudResult;
				}
			}
			if (minMem.contains("G") && maxMem.contains("M")) {
				return bocloudResult;
			}
			return new BocloudResult(true, "资源校验成功！");
		} catch (Exception e) {
			return new BocloudResult(false, "资源校验失败！");
		}
	}

	private BocloudResult createDaemonSet(DaemonSetModel model, CloudVendor cloudVendor, KubeNamespace kubeNamespace,
			RequestContext context) {
		try {
			BocloudResult bocloudResult = daemonSetDriver.create(cloudVendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			if (bocloudResult.isSuccess()) {
				KubeDaemonSet kubeDaemonSet = new KubeDaemonSet();
				DaemonSetModel daemonSetModel = (DaemonSetModel) bocloudResult.getData();
				BeanUtils.copyProperties(daemonSetModel, kubeDaemonSet);
				kubeDaemonSet.setCreatorId(context.getTarget());
				kubeDaemonSet.setMenderId(context.getTarget());
				kubeDaemonSet.setTenantId(context.getTenant());
				kubeDaemonSet.setVendorId(cloudVendor.getId());
				kubeDaemonSet.setNsId(kubeNamespace.getId());
				kubeDaemonSet.setAppId(kubeNamespace.getId());
				kubeDaemonSet.setAppName(kubeNamespace.getName());
				kubeDaemonSet.setVdcId(kubeNamespace.getVdcId());
				kubeDaemonSet.setPoolGroupId(kubeNamespace.getPoolGroupId());
				kubeDaemonSetRepository.save(kubeDaemonSet);
				Integer podCount = daemonSetModel.getPodCount();
				String limitsCpu = daemonSetModel.getLimitsCpu();
				String limitsMemory = daemonSetModel.getLimitsMemory();
				List<PodModel> podModels = daemonSetModel.getPodModels();
				if (null != podModels && !podModels.isEmpty()) {
					syncPods(podModels, context, cloudVendor, kubeNamespace);
				}
				// 发送给云平台统计队列对云平台重新统计
				JSONObject jsonObject = new JSONObject();
				jsonObject.put(Common.VENDORID, cloudVendor.getId());
				amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
			}
			return bocloudResult;
		} catch (Exception e) {
			logger.error("创建服务异常：" + e.getMessage());
			return new BocloudResult(false, "创建服务异常：" + e.getMessage());
		}

	}

	private void syncPods(List<PodModel> podModels, RequestContext context, CloudVendor cloudVendor,
			KubeNamespace kubeNamespace) {
		try {
			KubePod pod = null;
			for (PodModel createModel : podModels) {
				pod = new KubePod();
				BeanUtils.copyProperties(createModel, pod);
				pod.setCreatorId(context.getTarget());
				pod.setTenantId(context.getTenant());
				pod.setMenderId(context.getTarget());
				pod.setVendorId(cloudVendor.getId());
				pod.setNsId(kubeNamespace.getId());
				pod.setAppId(kubeNamespace.getId());
				pod.setAppName(kubeNamespace.getName());
				if (!StringUtils.isEmpty(createModel.getNodeName())) {
					KubeNode node = kubeNodeRepository.querByName(createModel.getNodeName(), cloudVendor.getId());
					if (null != node) {
						pod.setNodeId(node.getId());
					}
				}
				if (!StringUtils.isEmpty(createModel.getServiceName())) {
					KubeService service = kubeServiceRepository.querByName(createModel.getServiceName(),
							cloudVendor.getId());
					if (null != service) {
						pod.setServiceId(service.getId());
					}
				}
				kubePodRepository.save(pod);
				kubePodService.syncContainers(createModel.getKubeContainers(), pod, cloudVendor, context);
			}
		} catch (Exception e) {
			logger.error("同步Pod数据异常：" + e.getMessage());
		}
	}

	private BocloudResult createDeployment(DeploymentModel model, CloudVendor cloudVendor, KubeNamespace kubeNamespace,
			RequestContext context) {
		try {
			BocloudResult bocloudResult = deploymentDriver.create(cloudVendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			KubeDeployment deployment = new KubeDeployment();
			DeploymentModel deploymentModel = (DeploymentModel) bocloudResult.getData();
			BeanUtils.copyProperties(deploymentModel, deployment);
			deployment.setCreatorId(context.getTarget());
			deployment.setMenderId(context.getTarget());
			deployment.setTenantId(context.getTarget());
			deployment.setVendorId(cloudVendor.getId());
			deployment.setNsId(kubeNamespace.getId());
			deployment.setAppId(kubeNamespace.getId());
			deployment.setAppName(kubeNamespace.getName());
			deployment.setVdcId(kubeNamespace.getVdcId());
			deployment.setPoolGroupId(kubeNamespace.getPoolGroupId());
			kubeDeploymentRepository.save(deployment);
			Integer podCount = deploymentModel.getPodCount();
			String limitsCpu = deploymentModel.getLimitsCpu();
			String limitsMemory = deploymentModel.getLimitsMemory();
			List<PodModel> podModels = deploymentModel.getPodModels();
			if (null != podModels && !podModels.isEmpty()) {
				syncPods(podModels, context, cloudVendor, kubeNamespace);
			}
			// 发送给云平台统计队列对云平台重新统计
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(Common.VENDORID, cloudVendor.getId());
			amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
			return bocloudResult;
		} catch (Exception e) {
			logger.error("创建服务异常：" + e.getMessage());
			return new BocloudResult(false, "创建服务异常：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult create(KubeNamespace namespace, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(namespace.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			NamespaceModel model = new NamespaceModel();
			BeanUtils.copyProperties(namespace, model);
			BocloudResult create = namespaceDriver.create(vendor.getUuid(), model);
			if (create.isFailed()) {
				return new BocloudResult(false, create.getMessage());
			}
			NamespaceModel resultModel = (NamespaceModel) create.getData();
			BeanUtils.copyProperties(resultModel, namespace);
			namespace.preSave(context.getTarget(), context.getTarget(), vendor.getId());
			namespace.setTenantId(context.getTenant());
			this.kubeNamespaceRepository.save(namespace);
			return new BocloudResult(true, "添加成功");
		} catch (Exception e) {
			logger.error("create namespace error", e);
			return new BocloudResult(false, "添加失败");
		}
	}

	@Override
	public BocloudResult modify(KubeNamespace namespace, RequestContext context) {
		String path = KubeNamespace.class.getSimpleName() + "_" + namespace.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubeNamespace object = this.kubeNamespaceRepository.query(namespace.getId());
			if (null == object) {
				logger.warn("namespace does not exist!");
				return new BocloudResult(false, "数据不存在");
			}
			namespace.setMenderId(context.getTarget());
			this.kubeNamespaceRepository.update(namespace);
			return new BocloudResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify namespace fail:", e);
			return new BocloudResult(false, "修改失败");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = KubeNamespace.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubeNamespace namespace = this.kubeNamespaceRepository.query(id);
			if (null == namespace) {
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(namespace.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			Long tenantId = context.getTenant();
			if (null != tenantId && tenantId > 0) {
				BocloudResult listServices = listServices(id, null, context);
				if (listServices.isFailed()) {
					return listServices;
				}
				List<DeploymentModel> parseArray = JSON.parseArray(JSON.toJSONString(listServices.getData()),
						DeploymentModel.class);
				if (!ListTool.isEmpty(parseArray)) {
					return new BocloudResult(false, "当前应用下存在资源，不允许删除！");
				}
				List<KubeSecret> kubeSecrets = kubeSecretRepository.listByNsId(id, vendor.getId(), tenantId);
				if (!ListTool.isEmpty(kubeSecrets)) {
					return new BocloudResult(false, "当前应用下存在资源，不允许删除！");
				}
				List<KubeService> kubeServices = kubeServiceRepository.listByNsId(id, vendor.getId(), tenantId);
				if (!ListTool.isEmpty(kubeServices)) {
					return new BocloudResult(false, "当前应用下存在资源，不允许删除！");
				}
			}
			NamespaceModel model = new NamespaceModel();
			BeanUtils.copyProperties(namespace, model);
			BocloudResult bocloudResult = namespaceDriver.remove(model, vendor.getUuid());
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			this.kubeNamespaceRepository.remove(id, context.getTarget());
			return new BocloudResult(true, "删除成功");
		} catch (Exception e) {
			logger.error("Remove namespace error:", e);
			return new BocloudResult(false, "删除失败");
		}
	}

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

	/**
	 * 应用下的服务列表
	 */
	@Override
	public BocloudResult listServices(Long nsId, String params, RequestContext context) {
		try {
			List<DeploymentModel> parseArray = new ArrayList<>();
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(nsId);
			if (null == kubeNamespace) {
				return new BocloudResult(true, new ArrayList<>(), "查询成功！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(kubeNamespace.getVendorId());
			if (null == cloudVendor) {
				return new BocloudResult(false, "集群环境异常！");
			}
			List<KubeDeployment> kubeNamespaces = kubeDeploymentRepository.listByNsId(nsId, cloudVendor.getId(),
					context.getTenant());
			if (!ListTool.isEmpty(kubeNamespaces)) {
				for (KubeDeployment kubeDeployment : kubeNamespaces) {
					DeploymentModel deploymentModel = JSONObject.parseObject(JSON.toJSONString(kubeDeployment),
							DeploymentModel.class);
					deploymentModel.setServiceId(kubeDeployment.getId());
					parseArray.add(deploymentModel);
				}
			}
			List<KubeDaemonSet> kubeDaemonSets = kubeDaemonSetRepository.listByNsId(nsId, cloudVendor.getId(),
					context.getTenant());
			if (!ListTool.isEmpty(kubeDaemonSets)) {
				for (KubeDaemonSet kubeDaemonSet : kubeDaemonSets) {
					DeploymentModel deploymentModel = JSONObject.parseObject(JSON.toJSONString(kubeDaemonSet),
							DeploymentModel.class);
					deploymentModel.setServiceId(kubeDaemonSet.getId());
					parseArray.add(deploymentModel);
				}
			}
			return new BocloudResult(true, parseArray, "查询成功！");
		} catch (Exception e) {
			logger.error("查询失败：" + e.getMessage());
			return new BocloudResult(false, "查询失败：" + e.getMessage());
		}
	}

	/**
	 * 应用下的服务列表
	 */
	@Override
	public BocloudResult removeServices(Long nsId, String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			if (null == object) {
				return new BocloudResult(false, "参数格式错误！");
			}
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(nsId);
			if (null == kubeNamespace) {
				return new BocloudResult(true, new ArrayList<>(), "查询成功！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(kubeNamespace.getVendorId());
			if (null == cloudVendor) {
				return new BocloudResult(false, "集群环境异常！");
			}
			String kind = object.getString("kind");
			if (StringUtils.isEmpty(kind)) {
				return new BocloudResult(false, "参数格式错误！");
			}
			Long serviceId = object.getLong("serviceId");
			logger.info("删除容器资源：id={} | kind={} | 所属应用={}", serviceId, kind, kubeNamespace.getName());
			new Thread(new Runnable() {
				@Override
				public void run() {
					String operate = "kubernetes.service";
					try {
						BocloudResult bocloudResult = new BocloudResult(false, "删除失败！");
						String resourceUuid = null;
						Long vdcId = null;
						Long poolGourpId = null;
						String limitsCpu = null;
						String limitsMemory = null;
						Integer podCount = 0;
						List<Param> podParams = new ArrayList<Param>();
						switch (kind) {
						case KubeConstant.DEPLOYMENT:
							KubeDeployment kubeDeployment = kubeDeploymentRepository.query(serviceId);
							if (null == kubeDeployment) {
								resourceEventPublisher.send(new OperateResult(false, "资源不存在！", operate,
										MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
										OperateResult.OperateCategory.ResourceEvent, context));
								return;
							}
							resourceUuid = kubeDeployment.getUid();
							DeploymentModel deploymentModel = new DeploymentModel();
							deploymentModel.setNamespace(kubeNamespace.getName());
							deploymentModel.setName(kubeDeployment.getName());
							vdcId = kubeDeployment.getVdcId();
							poolGourpId = kubeDeployment.getPoolGroupId();
							limitsCpu = kubeDeployment.getLimitsCpu();
							limitsMemory = kubeDeployment.getLimitsMemory();
							podCount = kubeDeployment.getPodCount();
							bocloudResult = deploymentDriver.remove(deploymentModel, cloudVendor.getUuid());
							break;
						case KubeConstant.DAEMONSET:
							KubeDaemonSet kubeDaemonSet = kubeDaemonSetRepository.query(serviceId);
							if (null == kubeDaemonSet) {
								resourceEventPublisher.send(new OperateResult(false, "资源不存在！", operate,
										MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
										OperateResult.OperateCategory.ResourceEvent, context));
								return;
							}
							resourceUuid = kubeDaemonSet.getUid();
							DaemonSetModel daemonSetModel = new DaemonSetModel();
							daemonSetModel.setNamespace(kubeNamespace.getName());
							daemonSetModel.setName(kubeDaemonSet.getName());
							vdcId = kubeDaemonSet.getVdcId();
							poolGourpId = kubeDaemonSet.getPoolGroupId();
							limitsCpu = kubeDaemonSet.getLimitsCpu();
							limitsMemory = kubeDaemonSet.getLimitsMemory();
							podCount = kubeDaemonSet.getPodCount();
							bocloudResult = daemonSetDriver.remove(daemonSetModel, cloudVendor.getUuid());
							break;
						default:
							break;
						}
						logger.info("删除容器资源结果：{} {}", bocloudResult.isSuccess(), bocloudResult.getMessage());
						if (bocloudResult.isFailed()) {
							resourceEventPublisher.send(new OperateResult(false, "资源删除失败：" + bocloudResult.getMessage(),
									operate, MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
									OperateResult.OperateCategory.ResourceEvent, context));
							return;
						}
						if (KubeConstant.DEPLOYMENT.equalsIgnoreCase(kind)) {
							podParams.add(new Param(MapTools.simpleMap("deployment_uid", resourceUuid), Sign.EQ));
							kubeDeploymentRepository.remove(serviceId, context.getTarget());
						} else if (KubeConstant.DAEMONSET.equalsIgnoreCase(kind)) {
							podParams.add(new Param(MapTools.simpleMap("parent_resource_uid", resourceUuid), Sign.EQ));
							kubeDaemonSetRepository.remove(serviceId, context.getTarget());
						}
						// 删除对应pod
						podParams.add(new Param(MapTools.simpleMap("vendor_id", cloudVendor.getId()), Sign.EQ));
						podParams.add(new Param(MapTools.simpleMap("ns_name", kubeNamespace.getName()), Sign.EQ));
						List<KubePod> kubePods = kubePodRepository.listByParams(podParams);
						if (null != kubePods && !kubePods.isEmpty()) {
							for (KubePod kubePod : kubePods) {
								PodModel model = new PodModel();
								model.setName(kubePod.getName());
								model.setNamespace(kubePod.getNamespace());
								podDriver.remove(model, cloudVendor.getUuid());
								kubePodRepository.remove(kubePod.getId(), context.getTarget());
								kubeContainerRepository.remove(cloudVendor.getId(), kubePod.getId(),
										context.getTarget());
							}
						}
						resourceEventPublisher.send(new OperateResult(true, "资源删除成功！", operate,
								MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					} catch (Exception e) {
						logger.error("删除资源失败：" + e.getMessage());
						resourceEventPublisher.send(new OperateResult(false, "删除资源失败：" + e.getMessage(), operate,
								MapTools.simpleMap(Common.VENDORID, cloudVendor.getId()),
								OperateResult.OperateCategory.ResourceEvent, context));
					}
				}
			}).start();
			return new BocloudResult(true, "删除任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("删除失败：" + e.getMessage());
			return new BocloudResult(false, "删除失败：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult servicesTree(Long nsId, String params, RequestContext context) {
		try {
			List<DeploymentModel> parseArray = new ArrayList<>();
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(nsId);
			if (null == kubeNamespace) {
				return new BocloudResult(true, new ArrayList<>(), "查询成功！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(kubeNamespace.getVendorId());
			if (null == cloudVendor) {
				return new BocloudResult(false, "集群环境异常！");
			}
			List<KubeDeployment> kubeNamespaces = kubeDeploymentRepository.listByNsId(nsId, cloudVendor.getId(),
					context.getTenant());
			if (!ListTool.isEmpty(kubeNamespaces)) {
				parseArray.addAll(JSONObject.parseArray(JSON.toJSONString(kubeNamespaces), DeploymentModel.class));
			}
			List<KubeDaemonSet> kubeDaemonSets = kubeDaemonSetRepository.listByNsId(nsId, cloudVendor.getId(),
					context.getTenant());
			if (!ListTool.isEmpty(kubeDaemonSets)) {
				parseArray.addAll(JSONObject.parseArray(JSON.toJSONString(kubeDaemonSets), DeploymentModel.class));
			}
			kubeNamespace.setChilds(parseArray);
			return new BocloudResult(true, kubeNamespace, "查询成功！");
		} catch (Exception e) {
			logger.error("查询失败：" + e.getMessage());
			return new BocloudResult(false, "查询失败：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult listAllServices(Integer page, Integer rows, List<Param> params, Map<String, String> sorter,
			Boolean simple, RequestContext context) {
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = Lists.newArrayList();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			Long tenantId = context.getTenant();
			Long userId = context.getTarget();
			int total = 0;
			List<KubeDeployment> list = new ArrayList<KubeDeployment>();
			if (null != tenantId && 0L != tenantId) {
				total = this.kubeDeploymentRepository.count(tenantId, userId, null, null);
				list = this.kubeDeploymentRepository.list(page, rows, params, sorter, tenantId, userId, null, null);
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = this.kubeDeploymentRepository.serviceCount(tenantId);
				if (simple) {
				} else {
					list = this.kubeDeploymentRepository.serviceList(page, rows, params, sorter, tenantId);
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query namespace list fail:", e);
			return new BocloudResult(false, "查询失败");
		}
	}

	@Override
	public BocloudResult serviceDetail(String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			if (null == object) {
				return new BocloudResult(false, "参数格式错误！");
			}
			String kind = object.getString("kind");
			Long id = object.getLong("id");
			if (KubeConstant.DEPLOYMENT.equalsIgnoreCase(kind)) {
				KubeDeployment kubeDeployment = kubeDeploymentRepository.query(id);
				return new BocloudResult(true, kubeDeployment, "查询成功！");
			}
			if (KubeConstant.DAEMONSET.equalsIgnoreCase(kind)) {
				KubeDaemonSet kubeDaemonSet = kubeDaemonSetRepository.query(id);
				return new BocloudResult(true, kubeDaemonSet, "查询成功！");
			}
			return new BocloudResult(false, "查询失败！");
		} catch (Exception e) {
			logger.error("查询失败：" + e.getMessage());
			return new BocloudResult(false, "查询失败：" + e.getMessage());
		}
	}

	static class KubeConstant {
		final static String DEPLOYMENT = "Deployment";
		final static String DAEMONSET = "DaemonSet";
	}
}
