package com.bocloud.ims.service.resource;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.storage.BucketDriver;
import com.bocloud.cmp.model.BucketModel;
import com.bocloud.cmp.model.Butler;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.OperateResult;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.model.Sign;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.ims.entity.resource.Bucket;
import com.bocloud.ims.entity.resource.BucketObject;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.interfaces.resource.BucketService;
import com.bocloud.ims.repository.resource.BucketObjectRepository;
import com.bocloud.ims.repository.resource.BucketRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Maps;
import com.itextpdf.text.pdf.PdfStructTreeController.returnType;

/**
 * 存储桶业务操作
 * 
 * @date 2021/09/08
 */
@Service("bucketService")
public class BucketServiceImpl implements BucketService {

	private static Logger logger = LoggerFactory.getLogger(BucketServiceImpl.class);
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private BucketRepository bucketRepository;
	@Autowired
	private BucketObjectRepository bucketObjectRepository;
	@Autowired
	private CloudVendorRepository cloudVendorRepository;
	@Autowired
	private BucketDriver bucketDriver;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private AmqpTemplate amqpTemplate;

	@Override
	public BocloudResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple,
			RequestContext context) {
		try {
			GridBean gridBean = null;
			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			Long tenant = context.getTenant();
			if (null != tenant && 0L != tenant) {
				params.add(new Param(MapTools.simpleMap(Common.TENANTID, tenant), Sign.EQ));
			}
			sorter.put("create_time", Common.ONE);
			List<Bucket> list = bucketRepository.list(page, rows, params, sorter);
			int total = bucketRepository.count(params);
			gridBean = GridHelper.getBean(page, rows, total, list);
			return new BocloudResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list bucket failure:", e);
			return new BocloudResult(false, "查询失败", null, null);
		}
	}

	private String converter(long spaceUsed) {
		String value = null;
		if (spaceUsed > 1024 * 1024 * 1024) {
			value = new BigDecimal(spaceUsed).divide(new BigDecimal(1024 * 1024 * 1024), 2, RoundingMode.HALF_UP)
					.toString() + "GB";
		} else if (spaceUsed > 1024 * 1024) {
			value = new BigDecimal(spaceUsed).divide(new BigDecimal(1024 * 1024), 2, RoundingMode.HALF_UP).toString()
					+ "MB";
		} else if (spaceUsed > 1024) {
			value = new BigDecimal(spaceUsed).divide(new BigDecimal(1024), 2, RoundingMode.HALF_UP).toString() + "KB";
		} else {
			value = spaceUsed + "B";
		}
		return value;
	}

	@Override
	public BocloudResult create(Bucket bucket, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(bucket.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "云平台不存在");
			}
			Bucket bucket1 = bucketRepository.query(bucket.getName(),vendor.getId());
			if(null != bucket1){
				return new BocloudResult(false, "该存储桶名称已存在--"+bucket.getName());
			}
			bucket.setActualName(bucket.getName());
			BucketModel model = JSONObject.parseObject(JSONObject.toJSONString(bucket), BucketModel.class);
			new Thread(() -> {
				BocloudResult result = bucketDriver.create(model, vendor.getUuid(), bucket.getRegionId());
				if (result.isFailed()) {
					resourceEventPublisher.send(new OperateResult(false, "存储桶创建失败:" + result.getMessage(),
							vendor.getType().toLowerCase() + ".bucket.create", MapTools.simpleMap("vendorId", vendor.getId()),
							OperateResult.OperateCategory.ResourceEvent, context));
					return;
				}
				Bucket bucketSave = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), Bucket.class);
				bucketSave.setVendorId(vendor.getId());
				bucketSave.setCreatorId(context.getTarget());
				bucketSave.setMenderId(context.getTarget());
				bucketSave.setTenantId(context.getTenant());
				bucketRepository.save(bucketSave);
				resourceEventPublisher.send(new OperateResult(true, "存储桶创建成功！", "xsky.bucket.create",
						MapTools.simpleMap("vendorId", vendor.getId()), OperateResult.OperateCategory.ResourceEvent,
						context));

			}).start();
			return new BocloudResult(true, "创建任务已下发，正在执行......");
		} catch (Exception e) {
			logger.error("create bucket failure:", e);
			return new BocloudResult(false, "存储桶创建失败");
		}

	}

	@Override
	public BocloudResult remove(Long id, RequestContext context) {
		String path = Bucket.class.getSimpleName() + "_" + id;
		try (BocloudACLock lock = lockFactory.getACLock(path)) {
			Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
			Bucket bucket = bucketRepository.query(id);
			if (null == bucket) {
				logger.warn("bucket data not exist");
				return new BocloudResult(false, "数据不存在");
			}
			List<BucketObject> bucketObjects = bucketObjectRepository.listByBucketId(id, bucket.getVendorId());
			if (!ListTool.isEmpty(bucketObjects)) {
				return new BocloudResult(false, "存储桶下存在文件对象，无法删除");
			}
			CloudVendor vendor = cloudVendorRepository.query(bucket.getVendorId());
			if (null == vendor) {
				return new BocloudResult(false, "云平台不存在");
			}
			BucketModel model = new BucketModel();
			model.setName(bucket.getName());
			model.setBucketUuid(bucket.getBucketUuid());
			BocloudResult result = bucketDriver.remove(model, vendor.getUuid(), bucket.getRegionId());
			if (result.isFailed()) {
				return new BocloudResult(false, result.getMessage());
			}
			bucketObjectRepository.removeByBucketId(id, context.getTarget());
			bucketRepository.remove(id, context.getTarget());
			return new BocloudResult(true, "存储桶删除成功");
		} catch (Exception e) {
			logger.error("remove bucket fail:", e);
			return new BocloudResult(false, "存储桶删除失败");
		}
	}

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

	@Override
	public BocloudResult exists(String name, Long vendorId, String regionId, RequestContext context) {
		try {
			CloudVendor vendor = cloudVendorRepository.query(vendorId);
			if (null == vendor) {
				return new BocloudResult(false, "云平台不存在");
			}
			return bucketDriver.exists(name, vendor.getUuid(), regionId);
		} catch (Exception e) {
			logger.error("query bucket detail fail:", e);
			return new BocloudResult(false, "查询详情失败");
		}
	}

}
