package com.bocloud.ims.service.resource;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Mdisk;
import com.bocloud.ims.entity.resource.Storage;
import com.bocloud.ims.interfaces.resource.MdiskService;
import com.bocloud.ims.repository.resource.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service("mdiskService")
public class MdiskServiceImpl implements MdiskService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private ApplicationContext applicationContext;

	@Autowired
	private MdiskRepository mdiskRepository;
	@Autowired
	private CloudVendorRepository vendorRepository;
	@Autowired
	private StorageRepository storageRepository;
	@Autowired
	private StorageRaidRepository storageRaidRepository;
	@Autowired
	private DiskRepository diskRepository;

	@Override
	public BocloudResult<GridBean<Mdisk>> list(Pager pager, RequestContext context) {
		try {
			int page = pager.getPage();
			int rows = pager.getRows();
			List<Param> params = pager.getParams();
			Map<String, String> sorter = pager.getSorter();
			boolean simple = pager.getSimple();

			GridBean gridBean = null;
			int total = 0;
			total = mdiskRepository.count(params);
			if (simple) {
				List<SimpleBean> beans = mdiskRepository.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				List<Mdisk> list = mdiskRepository.list(page, rows, params, sorter);
				gridBean = new GridBean(page, rows, total, list);
			}
			return new BocloudResult<>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult create(Mdisk mdisk, RequestContext context) {
		try {
			if (mdisk.getStorageId() == null) {
				return new BocloudResult<>(false, "需要参数storageId");
			}
			Storage storage = storageRepository.get(mdisk.getStorageId());
			if (storage == null || storage.getDeleted()) {
				return new BocloudResult<>(false, "未找到存储或该存储已经被删除");
			}
			CloudVendor cloudVendor = vendorRepository.query(storage.getVendorId());
			if (cloudVendor == null || cloudVendor.getDeleted()) {
				return new BocloudResult<>(false, "未找到平台或该平台已经被删除");
			}
			MdiskService service = applicationContext.getBean(
					cloudVendor.getType().toLowerCase() + MdiskService.class.getSimpleName(), MdiskService.class);
			return service.create(mdisk, context);
		} catch (Exception e) {
			logger.error("创建失败：", e);
			return new BocloudResult<>(false, "创建失败：" + e.getMessage());
		}
	}

	@Override
	public BocloudResult<Mdisk> detail(long id) {
		try {
			Mdisk mdisk = mdiskRepository.get(id);
			return new BocloudResult<>(true, mdisk, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<List<SimpleBean>> getRaid(Long id, RequestContext context) {
		try {
			List<SimpleBean> storageRaid = storageRaidRepository.listNameByMdiskId(id).stream()
					.filter(simpleBean -> Pattern.matches("^\\w+[0-9]$", simpleBean.getName()))
					.collect(Collectors.toList());
			return new BocloudResult<>(true, storageRaid, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<List<SimpleBean>> getRaidByRaidName(Long id, String params, RequestContext context) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			if (object.getString("name") == null) {
				return new BocloudResult<>(false, "参数不正确");
			}
			String raidName = object.getString("name");
			List<SimpleBean> storageRaid = storageRaidRepository.getByNameAndMdiskId(raidName, id);
			return new BocloudResult<>(true, storageRaid, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

	@Override
	public BocloudResult<Mdisk> getCapacityForCreatePool(Long id, String params) {
		try {
			JSONObject object = JSONTools.isJSONObj(params);
			Mdisk mdisk = mdiskRepository.get(id);
			int diskCount = diskRepository.listByMdisk(id).size();
			int numD = 0;
			int numP = 0;
			int total;
			if (object.getString("name") != null && object.getString("tactics") != null
					&& !"RAID10".equals(object.getString("name"))) {
				String tactics = object.getString("tactics");
				if (Pattern.matches("^[0-9]D\\+[0-9]P$", tactics)) {
					numD = Integer.valueOf(tactics.substring(0, 1));
					numP = Integer.valueOf(tactics.substring(3, 4));
					total = numD + numP;
					if (total > diskCount) {
						mdisk.setPoolMessage("所选硬盘域的硬盘数无法满足当前RAID策略");
					} else {
						mdisk.setPoolMaxCapacity(Math.floor(Math.floor(mdisk.getFreeCapacity()) / total * numD));
					}
				} else if (Pattern.matches("^[0-9]D$", tactics)) {
					total = Integer.valueOf(tactics.substring(0, 1));
					if (total > diskCount) {
						mdisk.setPoolMessage("所选硬盘域的硬盘数无法满足当前RAID策略");
					} else {
						mdisk.setPoolMaxCapacity(Math.floor(Math.floor(mdisk.getFreeCapacity()) / total));
					}
				}
			} else if (object.getString("name") != null && "RAID10".equals(object.getString("name"))) {
				mdisk.setPoolMaxCapacity(Math.floor(Math.floor(mdisk.getFreeCapacity() / 2)));
			}
			return new BocloudResult<>(true, mdisk, "查询成功");
		} catch (Exception e) {
			logger.error("查询失败：", e);
			return new BocloudResult<>(false, "查询失败");
		}
	}

}
