package com.bocloud.ims.service.resource;

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

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 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.utils.Common;
import com.bocloud.ims.entity.common.MathUtils;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Disk;
import com.bocloud.ims.entity.resource.Storage;
import com.bocloud.ims.interfaces.resource.DiskService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.DiskPartitionRepository;
import com.bocloud.ims.repository.resource.DiskRepository;
import com.bocloud.ims.repository.resource.ServerRepository;
import com.bocloud.ims.repository.resource.StorageRepository;
import com.google.api.client.util.Maps;

@Service("diskService")
public class DiskServiceImpl implements DiskService {

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

	@Autowired
	private DiskRepository diskRepository;
	@Autowired
	private DiskPartitionRepository diskPartitionRepository;
	@Autowired
	private StorageRepository storageRepository;
	@Autowired
	private ServerRepository serverRepository;
	@Autowired
	private CloudVendorRepository vendorRepository;
	@Autowired
	private ApplicationContext applicationContext;

	@Override
	public BocloudResult<GridBean<Disk>> list(Pager pager, RequestContext context) {
		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);
			List<Disk> list = diskRepository.list(page, rows, params, sorter);
			for (Disk disk : list) {
				disk.setPartitions(diskPartitionRepository.listByDisk(disk.getId()));
				if (disk.getServerId() != null) {
					disk.setServer(serverRepository.query(disk.getServerId()));
				}
				disk.setUsedSize(Optional.ofNullable(disk.getUsedCapacity())
						.map(size -> MathUtils.round(size / 1024D / 1024D / 1024D, 2)).orElse(null));
			}
			int total = diskRepository.count(params);
			GridBean<Disk> gridBean = new GridBean(page, rows, total, list);
			return new BocloudResult<GridBean<Disk>>(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Get error message：", e);
			return new BocloudResult<GridBean<Disk>>(false, "查询失败");
		}
	}

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

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

}
