package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.ServerTemplateDriver;
import com.bocloud.cmp.model.ServerTemplateModel;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
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.common.Project;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ServerTemplate;
import com.bocloud.ims.entity.resource.ServerTemplateVersion;
import com.bocloud.ims.interfaces.resource.ServerTemplateService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ServerTemplateRepository;
import com.bocloud.ims.repository.resource.ServerTemplateVersionRepository;
import com.bocloud.ims.service.internal.SmsProjectService;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

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

/**
 * 虚拟机模板
 *
 * @author ymh
 * @时间 2019年3月9日
 */
@Service("serverTemplateService")
public class ServerTemplateServiceImpl implements ServerTemplateService {

	private static Logger logger = LoggerFactory.getLogger(ServerTemplateServiceImpl.class);
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private ServerTemplateDriver serverTemplateDriver;
	@Autowired
	private SmsProjectService smsProjectService;
	@Autowired
	private ServerTemplateRepository serverTemplateRepository;
	@Autowired
	private ServerTemplateVersionRepository serverTemplateVersionRepository;

	@Override
	public BocloudResult list(int page, int rows, List<Param> params, Map<String, String> sorter, boolean simple,
			RequestContext context) {
		List<ServerTemplate> list = Lists.newArrayList();
		int total = 0;
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			Long tenantId = context.getTenant();
			Long projectId = context.getProject();
			// 为租户下的用户
			if (null != tenantId && 0L != tenantId) {
				List<Project> projects = smsProjectService.projectsByCondition(context.getTarget(),
						context.getCatalog());
				List<Long> projectIds = new ArrayList<>();
				// 此时查询的是全部用户全部项目的信息
				if (null != projectId && 0L != projectId) {
					projectIds.add(projectId);
				} else if (!ListTool.isEmpty(projects)) {
					projects.forEach(project -> projectIds.add(project.getId()));
				} else {
					// 当前用户不属于任何项目，则登录之后查看不到任何信息
					projectIds.add(-1L);
				}
				total = serverTemplateRepository.count(params, projectIds);
				list = serverTemplateRepository.list(page, rows, params, sorter, projectIds);
				gridBean = GridHelper.getBean(page, rows, total, list);
			} else {
				total = serverTemplateRepository.count(params);
				if (simple) {
					if (0 == tenantId) {
						params.add(new Param(MapTools.simpleMap(Common.TENANTID, 0), Sign.EQ));
					}
					List<SimpleBean> beans = serverTemplateRepository.list(params, sorter);
					gridBean = new GridBean(1, 1, total, beans);
				} else {
					list = serverTemplateRepository.list(page, rows, params, sorter, null);
					gridBean = GridHelper.getBean(page, rows, total, list);
				}
			}
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list volume failure:", e);
			return new BocloudResult<>(false, "查询失败", null, null);
		}
	}

	@Override
	public BocloudResult create(String params, RequestContext context) {
		if (null == params || "".equals(params)) {
			return new BocloudResult<>(false, "参数格式错误！");
		}
		ServerTemplateModel serverTemplateModel = JSON.parseObject(params, ServerTemplateModel.class);
		try {
			CloudVendor cloudVendor = cloudVendorRepository.query(serverTemplateModel.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			BocloudResult bocloudResult = serverTemplateDriver.create(cloudVendor.getUuid(),
					serverTemplateModel.getRegion(), serverTemplateModel);
			return new BocloudResult<>(bocloudResult.isSuccess(), bocloudResult.getMessage());
		} catch (Exception e) {
			logger.error("get cloudvendor and reg error:", e);
			return new BocloudResult<>(false, "创建失败!");
		}
	}

	@Override
	public BocloudResult createTempalteVersion(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long vendorId = object.getLong(Common.VENDORID);
		String regionId = object.getString("regionId");
		try {
			CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			ServerTemplateModel serverTemplateModel = new ServerTemplateModel();
			BocloudResult bocloudResult = serverTemplateDriver.create(cloudVendor.getUuid(), regionId,
					serverTemplateModel);
			return new BocloudResult<>(bocloudResult.isSuccess(), bocloudResult.getMessage());
		} catch (Exception e) {
			logger.error("get cloudvendor and reg error:", e);
			return new BocloudResult<>(false, "创建失败!");
		}
	}

	@Override
	public BocloudResult removeTemplateVersion(String params, RequestContext context) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long defaultVersionId = object.getLong(Common.ID);
		String path = ServerTemplate.class.getSimpleName() + "_" + defaultVersionId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			ServerTemplateVersion serverTemplateVersion = serverTemplateVersionRepository.query(defaultVersionId);
			if (null == serverTemplateVersion) {
				logger.warn("serverTemplateVersion data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(serverTemplateVersion.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			ServerTemplateModel serverTemplateModel = new ServerTemplateModel();
			serverTemplateModel.setTemplateUuid(serverTemplateVersion.getTemplateUuid());
			List<Long> versions = new ArrayList<>();
			versions.add(serverTemplateVersion.getVersionNumber());
			serverTemplateModel.setVersions(versions);
			BocloudResult bocloudResult = serverTemplateDriver.removeTemplateVersion(cloudVendor.getUuid(),
					serverTemplateVersion.getRegion(), serverTemplateModel);
			if (bocloudResult.isFailed()) {
				return new BocloudResult<>(false, bocloudResult.getMessage());
			}
			return new BocloudResult<>(bocloudResult.isSuccess(), "删除成功！");
		} catch (Exception e) {
			logger.error("remove volume fail:", e);
			return new BocloudResult<>(false, "删除失败");
		}
	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = ServerTemplate.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			ServerTemplate serverTemplate = serverTemplateRepository.query(id);
			if (null == serverTemplate) {
				logger.warn("volume data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(serverTemplate.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			ServerTemplateModel serverTemplateModel = new ServerTemplateModel();
			serverTemplateModel.setTemplateUuid(serverTemplate.getTemplateUuid());
			BocloudResult bocloudResult = serverTemplateDriver.remove(cloudVendor.getUuid(),
					serverTemplate.getRegion(), serverTemplateModel);
			if (bocloudResult.isFailed()) {
				return new BocloudResult<>(false, bocloudResult.getMessage());
			}
			serverTemplateRepository.remove(serverTemplate.getId(), context.getTarget());
			return new BocloudResult<>(bocloudResult.isSuccess(), "删除成功！");
		} catch (Exception e) {
			logger.error("remove volume fail:", e);
			return new BocloudResult<>(false, "删除失败");
		}
	}

	@Override
	public BocloudResult detail(Long id) {
		try {
			ServerTemplate serverTemplate = serverTemplateRepository.query(id);
			if (null == serverTemplate) {
				logger.warn("volume data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			return new BocloudResult<>(true, serverTemplate, "查询详情成功");
		} catch (Exception e) {
			logger.error("query volume detail fail:", e);
			return new BocloudResult<>(false, "查询详情失败");
		}
	}

	@Override
	public BocloudResult modifyDafaultVersion(String params, Long userId) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long versionId = object.getLong(Common.ID);
		String path = ServerTemplate.class.getSimpleName() + "_" + versionId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			ServerTemplateVersion serverTemplateVersion = serverTemplateVersionRepository.query(versionId);
			if (null == serverTemplateVersion) {
				logger.warn("volume data not exist");
				return new BocloudResult<>(false, "版本不存在！");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(serverTemplateVersion.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			ServerTemplate serverTemplate = serverTemplateRepository.queryByUuid(cloudVendor.getId(),
					serverTemplateVersion.getTemplateUuid());
			ServerTemplateModel serverTemplateModel = new ServerTemplateModel();
			serverTemplateModel.setDefaultVersionNumber(serverTemplateVersion.getVersionNumber());
			serverTemplateModel.setTemplateUuid(serverTemplateVersion.getTemplateUuid());
			BocloudResult bocloudResult = serverTemplateDriver.modifyDefaultVersion(cloudVendor.getUuid(),
					serverTemplateVersion.getRegion(), serverTemplateModel);
			if (bocloudResult.isFailed()) {
				return new BocloudResult<>(false, bocloudResult.getMessage());
			}
			serverTemplateVersion.setDefaultVersion(true);
			serverTemplateVersionRepository.update(serverTemplateVersion);

			serverTemplate.setDefaultVersionNumber(serverTemplateVersion.getVersionNumber());
			serverTemplateRepository.update(serverTemplate);
			return new BocloudResult<>(bocloudResult.isSuccess(), bocloudResult.getMessage());
		} catch (Exception e) {
			logger.error("Modify serverTemplate fail:", e);
			return new BocloudResult<>(false, "修改失败");
		}
	}

	@Override
	public BocloudResult modify(String params, Long userId) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long serverTemplateId = object.getLong(Common.ID);
		String path = ServerTemplate.class.getSimpleName() + "_" + serverTemplateId;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			ServerTemplate serverTemplate = serverTemplateRepository.query(serverTemplateId);
			if (null == serverTemplate) {
				logger.warn("volume data not exist");
				return new BocloudResult<>(false, "数据不存在");
			}
			CloudVendor cloudVendor = cloudVendorRepository.query(serverTemplate.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor failure!");
				return new BocloudResult<>(false, "云平台不存在!");
			}
			ServerTemplateModel serverTemplateModel = new ServerTemplateModel();
			BocloudResult bocloudResult = serverTemplateDriver.modify(cloudVendor.getUuid(),
					serverTemplate.getRegion(), serverTemplateModel);
			return new BocloudResult<>(bocloudResult.isSuccess(), bocloudResult.getMessage());
		} catch (Exception e) {
			logger.error("Modify serverTemplate fail:", e);
			return new BocloudResult<>(false, "修改失败");
		}
	}
}
