package com.bocloud.ims.service.resource.azure.account;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.azure.account.BatchAccountDriver;
import com.bocloud.cmp.model.azure.account.BatchAccountModel;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.Common;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.ResourceGroup;
import com.bocloud.ims.entity.resource.azure.account.BatchAccount;
import com.bocloud.ims.entity.resource.azure.account.StorageAccount;
import com.bocloud.ims.interfaces.resource.azure.account.BatchAccountService;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ResourceGroupRepository;
import com.bocloud.ims.repository.resource.azure.account.BatchAccountRepository;
import com.bocloud.ims.repository.resource.azure.account.StorageAccountRepository;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Company: 博云 www.bocloud.com
 * @ClassName: BatchAccountServiceImpl
 * @Description:
 * @author: zhenpingLi/李振平
 * @date: 2020/7/24 14:17
 */
@Service("batchAccountService")
public class BatchAccountServiceImpl implements BatchAccountService {

    private static Logger logger = LoggerFactory.getLogger(BatchAccountServiceImpl.class);

    @Autowired
    private CloudVendorRepository vendorRepository;
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private BatchAccountRepository batchAccountRepository;
    @Autowired
    private BatchAccountDriver batchAccountDriver;
    @Autowired
    private ResourceGroupRepository resourceGroupRepository;
    @Autowired
    private StorageAccountRepository storageAccountRepository;

    @Override
    public BocloudResult<Void> create(BatchAccount entityParams, RequestContext context) {
        try {
            CloudVendor vendor = vendorRepository.query(entityParams.getVendorId());
            Assert.notNull(vendor, "平台不存在");
            if (null != batchAccountRepository.getByName(entityParams.getVendorId(), entityParams.getResourceGroupId(), entityParams.getName())) {
                return new BocloudResult<>(false, "名称已存在");
            }
            ResourceGroup resourceGroup = resourceGroupRepository.query(entityParams.getResourceGroupId());
            Assert.notNull(resourceGroup, "资源组不存在");
            StorageAccount storageAccount = storageAccountRepository.query(entityParams.getStorageAccountId());
            Assert.notNull(storageAccount, "存储账户不存在");

            BatchAccountModel model = new BatchAccountModel();
            BeanUtils.copyProperties(entityParams, model);
            model.setResourceGroupName(resourceGroup.getName());
            model.setStorageAccountUuid(storageAccount.getUuid());
            BocloudResult result = batchAccountDriver.create(vendor.getUuid(), entityParams.getRegionId(), model);
            if (result.isFailed()) {
                return new BocloudResult<>(false, result.getMessage());
            }
            model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), BatchAccountModel.class);
            BeanUtils.copyProperties(model, entityParams);
            entityParams.setCreatorId(context.getTarget());
            entityParams.setGmtCreate(new Date());
            entityParams.setProjectId(context.getProject());
            entityParams.setTenantId(context.getTenant());
            batchAccountRepository.save(entityParams);
            return new BocloudResult<>(true, "创建成功");
        } catch (Exception e) {
            logger.error("create batchAccount error!", e);
            return new BocloudResult<>(false, "创建失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> remove(Long id, RequestContext context) {
        String path = BatchAccount.class.getSimpleName() + "_" + id;
        try (BocloudACLock lock = lockFactory.getACLock(path)) {
            Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时");
            BatchAccount entity = batchAccountRepository.query(id);
            Assert.notNull(entity, "资源不存在");
            CloudVendor vendor = vendorRepository.query(entity.getVendorId());
            Assert.notNull(vendor, "平台不存在");
            BocloudResult result = batchAccountDriver.remove(vendor.getUuid(), entity.getRegionId(), entity.getUuid());
            if (result.isFailed()) {
                return new BocloudResult<>(false, result.getMessage());
            }
            batchAccountRepository.remove(id, context.getTarget());
            return new BocloudResult<>(true, "删除成功");
        } catch (Exception e) {
            logger.error("remove batchAccount error!", e);
            return new BocloudResult<>(false, "删除失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<GridBean<BatchAccount>> list(Pager pager, RequestContext context) {
        List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
        Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap());
        sorter.put("gmtCreate", Common.ONE);
        Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false);
        Integer page = Optional.ofNullable(pager.getPage()).orElse(1);
        Integer rows = Optional.ofNullable(pager.getRows()).orElse(10);
        try {
            GridBean<BatchAccount> gridBean;
            int total = batchAccountRepository.count(params);
            List<BatchAccount> list = this.batchAccountRepository.list(page, rows, params, sorter);
            gridBean = new GridBean<>(page, rows, total, list);
            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list batchAccount error!", e);
            return new BocloudResult<>(false, "查询失败:" + e.getMessage());
        }

    }

    @Override
    public BocloudResult<BatchAccount> detail(Long id, RequestContext context) {
        try {
            BatchAccount entity = batchAccountRepository.query(id);
            return new BocloudResult<>(true, entity, "查询详情成功");
        } catch (Exception e) {
            logger.error("query batchAccount error!", e);
            return new BocloudResult<>(false, "查询详情失败:" + e.getMessage());
        }
    }

    @Override
    public BocloudResult<Void> modify(BatchAccount entityParams, RequestContext context) {
        return null;
    }

    @Override
    public BocloudResult<Void> changeStorageAccount(BatchAccount entityParams, RequestContext context) {
        try {
            BatchAccount entity = batchAccountRepository.query(entityParams.getId());
            Assert.notNull(entity, "资源不存在");
            CloudVendor vendor = vendorRepository.query(entity.getVendorId());
            Assert.notNull(vendor, "平台不存在");
            StorageAccount storageAccount = storageAccountRepository.query(entityParams.getStorageAccountId());
            Assert.notNull(storageAccount, "存储账户不存在");

            BatchAccountModel model = new BatchAccountModel();
            BeanUtils.copyProperties(entityParams, model);
            model.setStorageAccountUuid(storageAccount.getUuid());
            model.setUuid(entity.getUuid());
            BocloudResult result = batchAccountDriver.changeStorageAccount(vendor.getUuid(), entityParams.getRegionId(), model);
            if (result.isFailed()) {
                return new BocloudResult<>(false, result.getMessage());
            }
            model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()), BatchAccountModel.class);
            BeanUtils.copyProperties(model, entity);
            entity.setStorageAccountId(storageAccount.getId());
            entity.setMenderId(context.getTarget());
            batchAccountRepository.update(entity);
            return new BocloudResult<>(true, "修改成功");
        } catch (Exception e) {
            logger.error("batchAccount changeStorageAccount error!", e);
            return new BocloudResult<>(false, "修改失败:" + e.getMessage());
        }
    }


}