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

import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.annotations.Log;
import com.bocloud.common.enums.BoCloudService;
import com.bocloud.common.model.BocloudResult;
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.resource.ObjectStorageContainer;
import com.bocloud.ims.entity.resource.ObjectStorageItem;
import com.bocloud.ims.interfaces.resource.ObjectStorageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * Created by hufy on 2017/9/4.
 */
@RestController
@RequestMapping("/objectstorage")
@Api(value = "对象存储", tags = "对象存储")
public class ObjectStorageController {

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

    @Autowired
    private ObjectStorageService objectStorageService;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    /**
     * 查询对象存储容器
     *
     * @param pager
     * @param context
     * @return
     * @throws Exception
     */
    @ApiOperation(tags={"CMC","CSC"},value = "查询对象存储容器",  httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "查询对象存储容器列表")
    @RequestMapping(value = "/container/list", method = {RequestMethod.POST})
    public BocloudResult<List<Map<String, Object>>> list(Pager pager, @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.listContainer(pager, context);
    }

    /**
     * 创建对象存储容器
     *
     * @param objectContainer
     * @param context
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "创建对象存储容器",  httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "创建对象存储容器")
    @RequestMapping(value = "/container/create", method = {RequestMethod.POST})
    public BocloudResult create(@RequestBody ObjectStorageContainer objectContainer,
                                @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.create(objectContainer, context);
    }

    /**
     * 查询对象存储容器详情
     *
     * @param id
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "查询对象存储容器详情",  httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "查询对象存储容器详情")
    @RequestMapping(value = "/container/{id}/detail", method = {RequestMethod.GET})
    public BocloudResult<ObjectStorageContainer> detail(@PathVariable(value = Common.ID) Long id,
                                @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.detailContainer(id, context);
    }

    /**
     * 删除对象存储容器
     *
     * @param id
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "删除对象存储容器",  httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "删除对象存储容器")
    @RequestMapping(value = "/container/{id}/remove", method = {RequestMethod.POST})
    public BocloudResult remove(@PathVariable(value = Common.ID) Long id,
                                @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.removeContainer(id, context);
    }

    /**
     * 查询对象存储项
     *
     * @return
     * @throws Exception
     */
    @ApiOperation(tags={"CMC","CSC"},value = "查询对象存储项",  httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "查询对象存储项")
    @RequestMapping(value = "/item/list", method = {RequestMethod.POST})
    public BocloudResult<List<ObjectStorageItem>> listItems(@RequestParam(value = Common.ID, required = true) Long containerId,
                                   @RequestParam(value = Common.PARAMS, required = false) String params,
                                   @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject jsonObj = JSONTools.isJSONObj(params);
        String name = jsonObj.getString("path");
        return objectStorageService.getTreeView(containerId, name, context);
    }

    /**
     * 创建对象存储容器
     *
     * @param params
     * @param context
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "创建对象存储容器",  httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "创建对象存储容器")
    @RequestMapping(value = "/item/create", method = {RequestMethod.POST})
    public BocloudResult createItem(@RequestParam(value = Common.PARAMS, required = true) String params,
                                    @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject object = JSONTools.isJSONObj(params);
        if (null != object) {
            String invokerPath = object.getString("invokerPath");
            ObjectStorageItem item = JSONObject.parseObject(object.toJSONString(), ObjectStorageItem.class);
            taskExecutor.submit(() -> objectStorageService.create(item, context, invokerPath));
            return new BocloudResult(true, "请求已提交,请等待处理结果");
        } else {
            return ResultTools.formatErrResult();
        }
    }

    /**
     * 查询对象存储容器详情
     *
     * @param id
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "查询对象存储容器详情",  httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "查询对象存储容器详情")
    @RequestMapping(value = "/item/{id}/detail", method = {RequestMethod.GET})
    public BocloudResult<ObjectStorageItem> detailItem(@PathVariable(value = Common.ID) Long id,
                                    @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.detailItem(id, context);
    }

    /**
     * 删除对象存储容器
     *
     * @param id
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "删除对象存储容器",  httpMethod = "DELETE")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "删除对象存储容器")
    @RequestMapping(value = "/item/{id}/remove", method = {RequestMethod.DELETE})
    public BocloudResult removeItem(@PathVariable(value = Common.ID) Long id,
                                    @RequestParam(value = Common.PARAMS, required = true) String params,
                                    @Value(Common.REQ_CONTEXT) RequestContext context) {
        return objectStorageService.removeItem(id, null, null, context);
    }

    /**
     * 删除对象存储容器
     *
     * @param
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "根据路径删除对象存储容器",  httpMethod = "POST")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "根据路径删除对象存储容器")
    @RequestMapping(value = "/item/removebypath", method = {RequestMethod.POST})
    public BocloudResult removeItemByPath(@RequestParam(value = Common.PARAMS, required = true) String params,
                                          @Value(Common.REQ_CONTEXT) RequestContext context) {
        JSONObject jsonObj = JSONTools.isJSONObj(params);
        String path = jsonObj.getString("path");
        Long containerId = jsonObj.getLong("containerId");
        return objectStorageService.removeItem(null, containerId, path, context);
    }

    /**
     * 下载对象存储容器
     *
     * @param id
     * @return
     */
    @ApiOperation(tags={"CMC","CSC"},value = "下载对象存储容器",  httpMethod = "GET")
    @Log(module = BoCloudService.IMS, target = "对象存储", operation = "下载对象存储容器")
    @RequestMapping(value = "/item/file/{id}/download", method = {RequestMethod.GET})
    public void download(@PathVariable(value = Common.ID) Long id, HttpServletResponse response,
                         @Value(Common.REQ_CONTEXT) RequestContext context) {
        InputStream inputStream = null;
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            inputStream = objectStorageService.download(id, context);
            if (inputStream != null) {
                IOUtils.copy(inputStream, outputStream, 8 * 1000 * 1000);
            }
        } catch (IOException e) {
            logger.error("获取输出流失败", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error("close stream failed", e);
                }
            }
        }
    }

}
