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.Component;
import org.springframework.util.Assert;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.kubernetes.PersistentVolumeDriver;
import com.bocloud.cmp.model.kubernetes.PersistentVolumeModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.kubernetes.KubeNamespace;
import com.bocloud.ims.entity.resource.kubernetes.KubePersistentVolume;
import com.bocloud.ims.interfaces.resource.kubernetes.KubePersistentVolumeService;
import com.bocloud.ims.repository.kubernetes.KubeNamespaceRepository;
import com.bocloud.ims.repository.kubernetes.KubePersistentVolumeRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Component("KubePersistentVolumeService")
public class KubePersistentVolumeServiceImpl implements KubePersistentVolumeService {

	private static final Logger logger = LoggerFactory.getLogger(KubePersistentVolumeServiceImpl.class);
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private KubePersistentVolumeRepository kubePersistentVolumeRepository;
	@Autowired
	private PersistentVolumeDriver persistentVolumeDriver;
	@Autowired
	private AmqpTemplate amqpTemplate;
	@Autowired
	private KubeNamespaceRepository kubeNamespaceRepository;
	@Autowired
	private LockFactory lockFactory;

	@Override
	public BocloudResult list(Pager pager) {
		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 = this.kubePersistentVolumeRepository.count(params);
			if (simple) {
				List<SimpleBean> beans = this.kubePersistentVolumeRepository.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				List<KubePersistentVolume> list = this.kubePersistentVolumeRepository.list(page, rows, params, sorter);
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query persistent volume list fail:", e);
			return new BocloudResult(false, "查询失败");
		}
	}

	@Override
	public BocloudResult create(KubePersistentVolume volume, RequestContext context) {
		try {
			String yamlText = volume.getYamlText();
			if (StringUtils.isEmpty(yamlText)) {
				return createPersistentVolume(volume, context);
			}
			CloudVendor vendor = cloudVendorRepository.query(volume.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			PersistentVolumeModel model = new PersistentVolumeModel();
			BeanUtils.copyProperties(volume, model);
			BocloudResult bocloudResult = persistentVolumeDriver.create(vendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return new BocloudResult(false, bocloudResult.getMessage());
			}
			PersistentVolumeModel createModel = (PersistentVolumeModel) bocloudResult.getData();
			BeanUtils.copyProperties(createModel, volume);
			volume.setCreatorId(context.getTarget());
			volume.setMenderId(context.getTarget());
			volume.setVendorId(vendor.getId());
			this.kubePersistentVolumeRepository.save(volume);
			// 发送给云平台统计队列对云平台重新统计
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(Common.VENDORID, vendor.getId());
			amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
			return new BocloudResult(true, "添加成功");
		} catch (Exception e) {
			logger.error("create persistent volume error", e);
			return new BocloudResult(false, "添加失败");
		}
	}

	private BocloudResult createPersistentVolume(KubePersistentVolume kubePersistentVolume, RequestContext context) {
		try {
			Long vendorId = kubePersistentVolume.getVendorId();
			Long namespaceId = kubePersistentVolume.getNamespaceId();
			KubeNamespace kubeNamespace = kubeNamespaceRepository.query(namespaceId);
			if (null == kubeNamespace) {
				return new BocloudResult(false, "数据异常！");
			}
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult(false, "集群信息异常！");
			}
			PersistentVolumeModel model = new PersistentVolumeModel();
			// TODO
			BocloudResult bocloudResult = persistentVolumeDriver.create(vendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return bocloudResult;
			}
			PersistentVolumeModel createModel = (PersistentVolumeModel) bocloudResult.getData();
			KubePersistentVolume volume = new KubePersistentVolume();
			BeanUtils.copyProperties(createModel, volume);
			volume.setCreatorId(context.getTarget());
			volume.setTenantId(context.getTenant());
			volume.setAppId(namespaceId);
			volume.setAppName(kubeNamespace.getName());
			volume.setMenderId(context.getTarget());
			volume.setVendorId(vendor.getId());
			this.kubePersistentVolumeRepository.save(volume);
			// 发送给云平台统计队列对云平台重新统计
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(Common.VENDORID, vendor.getId());
			amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
			return new BocloudResult(true, "存储创建成功！");
		} catch (Exception e) {
			return new BocloudResult(false, "创建存储异常：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult modify(KubePersistentVolume volume, RequestContext context) {
		String path = KubePersistentVolume.class.getSimpleName() + "_" + volume.getId();
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubePersistentVolume object = this.kubePersistentVolumeRepository.query(volume.getId());
			if (null == object) {
				logger.warn("persistent volume does not exist!");
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(object.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			String yamlText = volume.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");
			if (!object.getName().equals(newName)) {
				return new BocloudResult(false, "存储卷名称不允许修改！");
			}
			PersistentVolumeModel model = new PersistentVolumeModel();
			BeanUtils.copyProperties(volume, model);
			BocloudResult bocloudResult = persistentVolumeDriver.modify(vendor.getUuid(), model);
			if (bocloudResult.isFailed()) {
				return new BocloudResult(false, bocloudResult.getMessage());
			}
			PersistentVolumeModel createModel = (PersistentVolumeModel) bocloudResult.getData();
			BeanUtils.copyProperties(createModel, object);
			this.kubePersistentVolumeRepository.update(object);
			return new BocloudResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify persistent volume fail:", e);
			return new BocloudResult(false, "修改失败");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = KubePersistentVolume.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			KubePersistentVolume volume = this.kubePersistentVolumeRepository.query(id);
			if (null == volume) {
				return new BocloudResult(false, "数据不存在");
			}
			CloudVendor vendor = cloudVendorRepository.query(volume.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "获取云供应商失败");
			}
			PersistentVolumeModel model = new PersistentVolumeModel();
			BeanUtils.copyProperties(volume, model);
			BocloudResult bocloudResult = persistentVolumeDriver.remove(model, vendor.getUuid());
			if (bocloudResult.isFailed()) {
				return new BocloudResult(false, bocloudResult.getMessage());
			}
			this.kubePersistentVolumeRepository.remove(id, context.getTarget());
			// 发送给云平台统计队列对云平台重新统计
			JSONObject jsonObject = new JSONObject();
			jsonObject.put(Common.VENDORID, vendor.getId());
			amqpTemplate.convertAndSend("vendor.statistics.queue", jsonObject);
			return new BocloudResult(true, "删除成功");
		} catch (Exception e) {
			logger.error("Remove persistent volume error:", e);
			return new BocloudResult(false, "删除失败");
		}
	}

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

}
