package com.bocloud.ims.booter.controller.resource;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONArray;
import com.bocloud.ims.booter.annotation.ShowBindingBusiness;
import com.alibaba.fastjson.JSONArray;
import com.bocloud.ims.entity.common.Column;
import com.bocloud.ims.interfaces.resource.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.model.CloudServerBean;
import com.bocloud.cmp.model.KeypairParam;
import com.bocloud.cmp.model.SecurityGroupOperationParam;
import com.bocloud.cmp.vm.model.AttachNetworkParam;
import com.bocloud.cmp.vm.model.BatchModifyLabelParam;
import com.bocloud.cmp.vm.model.BatchSnapshotParam;
import com.bocloud.cmp.vm.model.DiskOperationParam;
import com.bocloud.cmp.vm.model.ResourceAssignParam;
import com.bocloud.cmp.vm.model.VmBatchOperationParam;
import com.bocloud.cmp.vm.model.VmDeleteParam;
import com.bocloud.cmp.vm.model.VmGenericParam;
import com.bocloud.cmp.vm.model.VmModifyParam;
import com.bocloud.cmp.vm.model.VmSnapshotParam;
import com.bocloud.common.annotations.Log;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Pager;
import com.bocloud.common.model.RequestContext;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.ResultTools;
import com.bocloud.ims.entity.params.QosParam;
import com.bocloud.ims.entity.params.ServerPerformanceParam;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.Keypair;
import com.bocloud.ims.entity.resource.Port;
import com.bocloud.ims.entity.resource.PortGroup;
import com.bocloud.ims.entity.resource.SecurityGroup;
import com.bocloud.ims.entity.resource.Volume;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(value = "虚拟机管理", tags = "虚拟机管理")
@RestController
@RequestMapping("/v1/vms")
public class CloudServerController {

    @Autowired
    private CloudServerService cloudServerService;

    @Autowired
    private ResourceAllocateService resourceAllocateService;
    @Autowired
    private RosProcessService rosProcessService;
    @Autowired
    private ExtFileDownLoadService extFileDownLoadService;
    @Autowired
    private VMExtendService vmExtendService;
    @Autowired
    private VMApplyService vMApplyService;

    /**
     * 虚拟机列表查询
     *
     * @param pager
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询虚拟机列表", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看虚拟机列表")
    @GetMapping
    public BocloudResult<GridBean<CloudServer>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.list(pager, context);
    }

    /**
     * 虚拟机列表查询
     *
     * @param condition
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "通过condition方式查询虚拟机列表", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看虚拟机列表")
    @GetMapping("/condition")
    public BocloudResult condition(@RequestParam(value = Common.PAGE, required = false) Integer page,
        @RequestParam(value = Common.ROWS, required = false) Integer rows,
        @RequestParam(Common.CONDITION) String condition, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.condition(page, rows, condition, context);
    }

    /**
     * 查看虚拟机统计
     *
     * @param range
     * @param hostId
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询虚拟机统计", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看虚拟机统计")
    @GetMapping("/file")
    public BocloudResult statistics(@RequestParam(value = "range") String range,
        @RequestParam(value = "hostId") Long hostId, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.stats(range, hostId, context);
    }

    /**
     * @param context
     * @return com.bocloud.common.model.BocloudResult
     * @Author: lxy
     * @Description: 云平台下虚拟机信息（个数、cpu、men、disk）统计
     * @Date 2021/5/26 16:42
     * @Param hostId
     * @throws:
     **/
    @ApiOperation(tags = {"CMC", "CSC"}, value = "宿主机下虚拟机信息统计", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "宿主机下虚拟机信息统计")
    @GetMapping("/selectAllByVendorId")
    public BocloudResult selectAllByVendorId(@RequestParam(value = "vendorId", required = false) Long vendorId,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.selectAllByVendorId(vendorId, context);
    }

    /**
     * 导出虚拟机列表
     *
     * @param pager
     * @param
     * @param condition
     * @param context
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "导出虚拟机列表", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "导出vcenter虚拟机列表")
    @GetMapping("/download")
    public BocloudResult download(@RequestParam(value = "columnStr") String columnStr, Pager pager,
        @RequestParam(value = Common.CONDITION, required = false) String condition,
                                  @Value(Common.REQ_CONTEXT) RequestContext context, HttpServletRequest request, HttpServletResponse response) {
        List<Column> columns = JSONArray.parseArray(columnStr).toJavaList(Column.class);
        BocloudResult<Map<String, Object>> bocloudResult =
            extFileDownLoadService.vmDownload(pager, condition, columns, context, "vm");
        if (bocloudResult.isSuccess()) {
            String content;
            try {
                Map<String, Object> result = bocloudResult.getData();
                String fileName = result.get("fileName").toString();
                if (fileName.contains("pdf")) {
                    response.setContentType("application/pdf");
                } else {
                    response.setContentType("application/vnd.ms-excel");
                }
                final String userAgent = request.getHeader("user-agent").toLowerCase();
                if (userAgent.contains("trident") || userAgent.contains("edge")) {
                    fileName = URLEncoder.encode(fileName, "UTF-8");
                } else {
                    fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1");
                }
                response.setCharacterEncoding("utf-8");
                response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
                OutputStream outputStream = response.getOutputStream();
                content = (String)result.get("data");
                if (content != null) {
                    byte[] bytes = Base64.getDecoder().decode(content);
                    outputStream.write(bytes);
                    outputStream.close();
                }
            } catch (Exception e) {
                return new BocloudResult(false, "内部错误");
            }
        }
        return bocloudResult;
    }

    /**
     * 添加虚拟机
     *
     * @param params
     *            虚拟机属性信息的json字符串，在数据转换时会发生异常，对外抛出400异常【Bad Request】
     * @return 添加结果
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "添加虚拟机", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "添加虚拟机")
    @PostMapping
    public BocloudResult create(@RequestBody VmGenericParam params, @Value(Common.REQ_CONTEXT) RequestContext context) {
        String action = params.getAction();
        if ("create".equalsIgnoreCase(action)) {
            return cloudServerService.create(params, context);
        } else if ("ResourcesPool".equalsIgnoreCase(action)) {
            // 指定资源池创建虚拟机
            return cloudServerService.createInResPool(params, context);
        }
        return new BocloudResult(false, "无效操作！");
    }

    /**
     * 创建快照
     *
     * @param id
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "创建快照", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "创建快照")
    @PostMapping("/{id}/snapshots")
    public BocloudResult snapshot(@PathVariable(value = Common.ID) Long id, @RequestBody VmSnapshotParam params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        params.setServerId(id);
        return cloudServerService.snapshot(params, context);
    }

    /**
     * 批量创建快照
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "批量创建快照", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "创建快照")
    @PostMapping("/snapshots")
    public BocloudResult batchSnapshot(@RequestBody BatchSnapshotParam params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.batchSnapshot(params, context);
    }

    /**
     * 修改虚拟机
     *
     * @param bean
     * @param id
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "修改虚拟机", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改虚拟机")
    @PutMapping("/{id}")
    public BocloudResult modify(@RequestBody CloudServerBean bean, @PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        bean.setId(id);
        return cloudServerService.modify(bean, context, null);
    }

    /**
     * 删除虚拟机
     *
     * @param id
     *            虚拟机ID
     * @return 操作结果
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "删除虚拟机", httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "删除虚拟机")
    @DeleteMapping("/{id}")
    public BocloudResult remove(@PathVariable(value = Common.ID) Long id,
        @RequestBody(required = false) VmDeleteParam vmDeleteParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (null != vmDeleteParam) {
            vmDeleteParam.setId(id);
        }
        return cloudServerService.remove(id, vmDeleteParam, context);
    }

    /**
     * 批量删除虚拟机
     *
     * @param ids
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "批量删除虚拟机", httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "删除虚拟机")
    @DeleteMapping
    public BocloudResult batchRemove(@RequestBody List<Long> ids, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.batchRemove(ids, context);
    }

    /**
     * 更新物理机的资源分组
     *
     * @param id
     * @param resourceGroup
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "更新资源分组", httpMethod = "PUT")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "更新资源分组")
    @PutMapping("/groups")
    public BocloudResult updateResourceGroup(@RequestParam(value = Common.ID) String id,
        @RequestParam(value = "resourceGroup") String resourceGroup,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (StringUtils.isNotEmpty(id)) {
            String[] ids = id.split(",");
            return vmExtendService.updateResourceGroup(ids, resourceGroup, context.getTarget());
        }
        return new BocloudResult(false, "暂不支持");
    }

    /**
     * 查看虚拟机详细信息
     *
     * @param id
     * @param context
     * @param action
     * @param params
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查看虚拟机详情", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看虚拟机详情")
    @GetMapping("/{id}")
    public BocloudResult detail(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action,
        @RequestParam(value = Common.PARAMS, required = false) String params) {
        return cloudServerService.details(id, context, action, params);
    }

    /**
     * 虚拟机操作类
     *
     * @param id
     * @param context
     * @param params
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机操作", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "克隆虚拟机")
    @PatchMapping("/{id}")
    public BocloudResult operation(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context, @RequestBody VmGenericParam params) {
        return cloudServerService.operations(id, params, context);
    }

    /**
     * 虚拟机磁盘操作
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机磁盘操作", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机磁盘操作")
    @PatchMapping("/disks")
    public BocloudResult diskOperation(@RequestBody DiskOperationParam params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.diskOperation(params, context);
    }

    /**
     * 虚拟机批量操作
     *
     * @param batchOperationParam
     * @param action
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机批量操作", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "批量重启虚拟机")
    @PatchMapping
    public BocloudResult batchOperations(@RequestBody VmBatchOperationParam batchOperationParam,
        @RequestParam(value = Common.ACTION, required = false) String action,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.batchOperations(batchOperationParam, context);
    }

    /**
     * 获取监控数据接口
     *
     * @param id
     * @param params
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "获取监控数据", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "获取监控数据")
    @GetMapping("/{id}/metrics")
    public BocloudResult performance(@PathVariable(value = Common.ID) Long id,
        @RequestBody(required = false) ServerPerformanceParam params) {
        return vmExtendService.performance(params);
    }

    /**
     * 网络列表
     *
     * @param id
     *            任务ID
     * @return 操作结果
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查看网络列表", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看网络列表")
    @GetMapping("/{id}/networks")
    public BocloudResult<List<PortGroup>> networks(@PathVariable(value = Common.ID) Long id) {
        return vmExtendService.networks(id);
    }

    /**
     * 根据VDC 集群 宿主机 查询网络标签
     *
     * @param id
     *            任务ID
     * @return 操作结果
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查看网络列表", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看网络列表")
    @GetMapping("/networks")
    public BocloudResult<List<PortGroup>> networkResources(
        @RequestParam(value = "resourceIds", required = false) String resourceIds,
        @RequestParam(value = "type", required = false) String type) {
        return vmExtendService.networkResources(resourceIds, type);
    }

    /**
     * 修改虚拟机密码(openstack)
     *
     * @param id
     * @param vendorId
     * @param password
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "修改OpenStack虚拟机密码", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改OpenStack虚拟机密码")
    @PatchMapping("/{id}/password")
    public BocloudResult osChangePwd(@PathVariable(value = Common.ID) Long id, @RequestBody VmModifyParam vmModifyParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.osChangePwd(vmModifyParam.getVendorId(), id, vmModifyParam.getPassword(), context);
    }

    /**
     * 挂载网卡(openstack)
     *
     * @param id
     * @param attachNetworkParam
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "挂载OpenStack网卡", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "挂载OpenStack网卡")
    @PostMapping("/{id}/networks")
    public BocloudResult attachNetwork(@PathVariable(value = Common.ID) Long id,
        @RequestBody AttachNetworkParam attachNetworkParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        attachNetworkParam.setId(id);
        return vmExtendService.attachNetwork(attachNetworkParam, context);
    }

    /**
     * 挂载网卡(openstack)
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "批量挂载OpenStack网卡", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "挂载OpenStack网卡")
    @PostMapping("/networks")
    public BocloudResult batchAttachNetwork(@RequestBody List<AttachNetworkParam> params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.batchAttachNetwork(params, context);
    }

    /**
     * 卸载网卡(openstack)
     *
     * @param id
     * @param portId
     * @param context
     * @param action
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "卸载OpenStack网卡", httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "卸载OpenStack网卡")
    @DeleteMapping("/{id}/networks")
    public BocloudResult detachNetwork(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = "portId", required = false) Long portId,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.detachNetworks(id, portId, context, action);
    }

    /**
     * 设置网卡qos
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "设置网卡qos", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "设置网卡qos")
    @PostMapping("/{id}/networks/qos")
    public BocloudResult addPortPolicy(@PathVariable(value = Common.ID) Long id, @RequestBody QosParam params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        params.setId(id);
        return vmExtendService.addPortPolicy(JSONObject.toJSONString(params), context);
    }

    /**
     * 修改配置
     *
     * @param id
     * @param vmModifyParam
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "修改OpenStack虚拟机配置", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改OpenStack虚拟机配置")
    @PatchMapping("/{id}/flavors")
    public BocloudResult flavors(@PathVariable(value = Common.ID) Long id, @RequestBody VmModifyParam vmModifyParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        vmModifyParam.setId(id);
        return vmExtendService.resizes(vmModifyParam, context);
    }

    @ApiOperation(tags = {"CMC", "CSC"}, value = "修改虚拟机配置", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改虚拟机配置")
    @PatchMapping("/{id}/resize")
    public BocloudResult resize(@PathVariable(value = Common.ID) Long id, @RequestBody String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vMApplyService.upgradeConfig(params, context);
    }

    /**
     * 查询虚拟机绑定的端口
     *
     * @param id
     * @param params
     * @param context
     * @param action
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询虚拟机绑定的端口", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查询虚拟机绑定的端口")
    @GetMapping("/{id}/ports")
    public BocloudResult<List<Port>> listPort(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.PARAMS, required = false) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.ports(params, context, action);
    }

    /**
     * 查询高于虚拟机当前配置的规格
     *
     * @param params
     * @param context
     * @param action
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询高于虚拟机当前配置的规格", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查询高于虚拟机当前配置的规格")
    @GetMapping("/flavors")
    public BocloudResult listFlavor(@RequestParam(value = Common.PARAMS, required = false) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.flavors(params, context, action);
    }

    /**
     * 修改账号密码
     *
     * @param account
     * @param password
     * @param id
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询高于虚拟机当前配置的规格", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改账号密码")
    @PutMapping("/{id}/accounts")
    public BocloudResult modifyAccount(@PathVariable(value = Common.ID) Long id,
        @RequestBody VmModifyParam vmModifyParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.modifyAccount(id, vmModifyParam.getAccount(), vmModifyParam.getPassword(), context);
    }

    /**
     * 查看账号密码
     *
     * @param id
     *            虚拟机ID
     * @return 操作结果
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查看账号密码", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看账号密码")
    @GetMapping("/{id}/accounts")
    public BocloudResult<CloudServer> detailAccount(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.queryAccount(id);
    }

    /**
     * 虚拟机CPU或内存热插拔设置
     *
     * @param id
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机CPU或内存热插拔设置", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机CPU或内存热插拔设置")
    @PatchMapping("/{id}/pluggable")
    public BocloudResult hotConfigEnable(@PathVariable(value = Common.ID) Long id,
        @RequestBody VmModifyParam vmModifyParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (null != vmModifyParam) {
            return vmExtendService.hotConfigEnable(vmModifyParam.getServerId(), context.getTarget(),
                vmModifyParam.getCpuHotEnable(), vmModifyParam.getMemHotEnable());
        }
        return ResultTools.formatErrResult();
    }

    /**
     * 获得vcenter访问remote console的ticket
     *
     * @param id
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "获得vcenter访问remote console的ticket", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "获得vcenter访问remote console的ticket")
    @GetMapping("/{id}/tickets")
    public BocloudResult getTicket(@PathVariable(value = Common.ID) Long id) {
        return vmExtendService.getTicket(id);
    }

    /**
     * 获得vcenter访问vmrc控制台
     *
     * @param id
     * @param action
     * @param vncType
     * @param serverId
     * @param region
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "获得vcenter访问vmrc控制台", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "获得vcenter访问vmrc控制台")
    @GetMapping("/{id}/console")
    public BocloudResult console(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.ACTION, required = false) String action,
        @RequestParam(value = "vncType", required = false) String vncType,
        @RequestParam(value = "serverId", required = false) String serverId,
        @RequestParam(value = "region", required = false) String region,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.vncconsoles(id, vncType, serverId, region, context, action);
    }

    /**
     * 挂载/卸载 vmware tools安装镜像
     *
     * @param id
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "挂载vmware tools安装镜像", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "挂载vmware tools安装镜像")
    @PatchMapping("/{id}/vmtools")
    public BocloudResult mountToolsInstaller(@PathVariable(value = Common.ID) Long id,
        @RequestBody VmModifyParam vmModifyParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (null == vmModifyParam) {
            return new BocloudResult<>(false, "参数格式错误");
        }
        return vmExtendService.vmtools(id, vmModifyParam, context);
    }

    /**
     * 根据集群维度或平台维度汇总虚拟机数量
     *
     * @param params
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "根据集群维度或平台维度汇总虚拟机数量", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "根据集群维度或平台维度汇总虚拟机数量")
    @GetMapping("/summary")
    public BocloudResult chart(@RequestParam(value = Common.PARAMS, required = true) String params) {
        return vmExtendService.chart(params);
    }

    /**
     * 分配给用户
     *
     * @param id
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机用户分配", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机用户分配")
    @PostMapping("/users")
    public BocloudResult assign(@RequestBody ResourceAssignParam vmAssignParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return resourceAllocateService.assign(JSONObject.parseObject(JSON.toJSONString(vmAssignParam)),
            vmAssignParam.getResourceCategory(), context);
    }

    /**
     * 批量加入安全组
     *
     * @param id
     * @param securityGroupOperationParam
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "批量加入安全组", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "批量加入安全组")
    @PostMapping("/{id}/sgroups")
    public BocloudResult joinsgrouplist(@PathVariable(value = Common.ID) Long id,
        @RequestBody SecurityGroupOperationParam securityGroupOperationParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.joinGroups(securityGroupOperationParam, context);
    }

    /**
     * 移除安全组
     *
     * @param id
     * @param groupId
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "移除安全组", httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "移除安全组")
    @DeleteMapping("/{id}/sgroups")
    public BocloudResult leaveSGroup(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = "groupId", required = true) Long groupId,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.leaveSGroup(id, groupId, context);
    }

    /**
     * 查询虚拟机绑定的安全组
     *
     * @param id
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询虚拟机绑定的安全组", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查询虚拟机绑定的安全组")
    @GetMapping("/{id}/sgroups")
    public BocloudResult<List<SecurityGroup>> listSGroup(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.sgroups(id, context, action);
    }

    /**
     * 回收租户虚拟机
     *
     * @param id
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "回收租户虚拟机", httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "回收租户虚拟机")
    @DeleteMapping("/users")
    public BocloudResult reclaim(@RequestBody ResourceAssignParam vmAssignParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (null == vmAssignParam) {
            return new BocloudResult<>(false, "参数格式错误");
        }
        return resourceAllocateService.reclaim(vmAssignParam, vmAssignParam.getResourceCategory(), context);
    }

    /**
     * 虚拟机标记为模板
     *
     * @param id
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机标记为模板", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机标记为模板")
    @PostMapping("/{id}/templates")
    public BocloudResult markAsTemplate(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.markAsTemplate(id, context);
    }

    /**
     * 修改虚拟机密码
     *
     * @param id
     * @param vmModifyParam
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "修改虚拟机密码", httpMethod = "PUT")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "修改虚拟机密码")
    @PutMapping("/{id}/password")
    public BocloudResult vcChangePasswd(@PathVariable(value = Common.ID) Long id,
        @RequestBody VmModifyParam vmModifyParam, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.vcChangePasswd(vmModifyParam, context);
    }

    /**
     * 批量配置虚拟机标签
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "批量配置虚拟机标签", httpMethod = "PUT")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "批量配置虚拟机标签")
    @PutMapping("/tags")
    public BocloudResult batchModifyLabel(@RequestBody BatchModifyLabelParam params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.batchModifyLabel(params, context);
    }

    /**
     * 扩容vcenter虚拟机磁盘容量
     *
     * @param id
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "扩容vcenter虚拟机磁盘容量", httpMethod = "PUT")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "扩容vcenter虚拟机磁盘容量")
    @PutMapping("/{id}/disks")
    public BocloudResult diskExtend(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.PARAMS, required = true) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.diskExtend(params, context);
    }

    /**
     * 查询模板
     *
     * @param id
     * @param vendorId
     * @param vdcId
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询模板", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查询模板")
    @GetMapping("/{id}/templates")
    public BocloudResult<List<CloudServer>> listTemplate(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.VENDORID, required = false) Long vendorId,
        @RequestParam(value = "vdcId", required = false) Long vdcId) {
        return cloudServerService.listTemplate(vendorId, vdcId);
    }

    /**
     * 安装vmware tools
     *
     * @param id
     * @param params
     * @param context
     * @param action
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "安装vmware tools", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "安装vmware tools")
    @PostMapping("/{id}/vmtools")
    public BocloudResult vmToolsInstall(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.PARAMS, required = true) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.vmToolsInstalls(params, context, action);

    }

    /**
     * 创建k8s虚拟机
     *
     * @param params
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "创建k8s虚拟机", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "创建k8s虚拟机")
    @PostMapping("/k8s")
    public BocloudResult createK8sVm(@RequestParam(value = Common.PARAMS) String params) {
        JSONObject object = JSONObject.parseObject(params);
        if (null == object) {
            return ResultTools.formatErrResult();
        }
        return rosProcessService.createK8sVm(object);
    }

    /**
     * 查询虚拟机绑定的秘钥
     *
     * @param id
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询虚拟机绑定的秘钥", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查询虚拟机绑定的秘钥")
    @GetMapping("/{id}/keypairs")
    public BocloudResult<List<Keypair>> listBindedKeyPair(@PathVariable(value = Common.ID) Long id,
        @Value(Common.REQ_CONTEXT) RequestContext context,
        @RequestParam(value = Common.ACTION, required = false) String action) {
        return vmExtendService.keypairs(id, context, action);
    }

    /**
     * 虚拟机绑定秘钥
     *
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机绑定秘钥", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机绑定秘钥")
    @PatchMapping("/{id}/keypairs")
    public BocloudResult bindKeypair(@PathVariable(value = Common.ID) Long id, @RequestBody KeypairParam keypairParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.bindKeypairs(keypairParam, context);
    }

    /**
     * 查看虚拟机存储卷
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "查看虚拟机存储卷", httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "查看虚拟机存储卷")
    @GetMapping("/volumes")
    public BocloudResult<List<Volume>> listVolume(@RequestParam(value = Common.PARAMS, required = false) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject jsonObject = JSONTools.isJSONObj(params);
        if (null != jsonObject) {
            return vmExtendService.listVolume(params);
        }
        return ResultTools.formatErrResult();
    }

    /**
     * 挂载卷
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机挂载卷", httpMethod = "PATCH")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机挂载卷")
    @PatchMapping("/{id}/volumes")
    public BocloudResult attachVolume(@RequestParam(value = Common.PARAMS, required = true) String params,
        @RequestParam(value = Common.ACTION, required = false) String action,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return vmExtendService.volumes(params, action, context);
    }

    /**
     * 虚拟机捕获映像对虚拟机使用卷的操作
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机捕获映像对虚拟机使用卷的操作", httpMethod = "PUT")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机捕获映像对虚拟机使用卷的操作")
    @PutMapping("/{id}/images")
    public BocloudResult beforeCaptureImage(@RequestParam(value = Common.PARAMS, required = true) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject object = JSONTools.isJSONObj(params);
        if (null != object) {
            return vmExtendService.beforeCaptureImage(params, context);
        }
        return ResultTools.formatErrResult();
    }

    /**
     * 虚拟机捕获映像
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags = {"CMC", "CSC"}, value = "虚拟机捕获映像", httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "虚拟机", operation = "虚拟机捕获映像")
    @PostMapping("/{id}/images")
    public BocloudResult captureImage(@PathVariable(value = Common.ID) Long id,
        @RequestParam(value = Common.PARAMS, required = true) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject object = JSONTools.isJSONObj(params);
        if (null != object) {
            return vmExtendService.captureImage(params, context);
        }
        return ResultTools.formatErrResult();
    }

    @ApiOperation(tags = {"CMC", "CSC"}, value = "查询可绑定虚拟机", response = BocloudResult.class, httpMethod = "GET",
        produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/availableVms")
    public BocloudResult listAllVm(@RequestBody VmGenericParam vmGenericParam,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        if (null != vmGenericParam) {
            return cloudServerService.listAvailableVm(vmGenericParam.getVendorId(), vmGenericParam.getRegionId(),
                context);
        }
        return ResultTools.formatErrResult();
    }

    @ApiOperation(value = "流水号配置", response = BocloudResult.class, httpMethod = "POST",
        produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(value = "/configSeq")
    public BocloudResult configSeq(@RequestParam(value = Common.PARAMS, required = false) String params,
        @Value(Common.REQ_CONTEXT) RequestContext context) {
        return cloudServerService.configSeq(params, context);
    }

    @ApiOperation(value = "流水号配置详情", response = BocloudResult.class, httpMethod = "GET",
        produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping(value = "/getBusinessById/{id}")
    public BocloudResult getBusinessById(@PathVariable(value = Common.ID) Long id) {
        return cloudServerService.getBusinessById(id);
    }
}
