package io.renren.modules.sys.controller.algs;

import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Image;
import io.minio.errors.*;
import io.renren.common.annotation.SysLog;
import io.renren.common.utils.*;
import io.renren.common.validator.ValidatorUtils;
import io.renren.common.validator.group.AddGroup;
import io.renren.common.validator.group.UpdateGroup;
import io.renren.modules.sys.entity.algs.AlgorithmModel;
import io.renren.modules.sys.entity.algs.AlgorithmModel_Vo;
import io.renren.modules.sys.entity.algs.AlgorithmTemplate;
import io.renren.modules.sys.entity.algs.FileTest;
import io.renren.modules.sys.service.impl.AlgsModelsServiceImpl;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;

import static io.renren.common.utils.ShiroUtils.getUserId;

/**
 * @Author: Ivan Q
 * @Date: 2021/6/8 9:34
 */
@RestController
@RequestMapping("/algs/models")
public class algModelsController {

    @Autowired
    AlgsModelsServiceImpl algsModelsService;
    /**
     * 所有列表
     */
    @GetMapping("/list")
    /*
    把这个@RequiresPermissions注解去掉，那么如果在角色管理中，去掉查看功能的话也可以获取列表，但是没有每条数据右侧的查看按钮；
    不去掉的话那就是必须在打开查看模板功能，否则不能获取列表数据。
     */
    @RequiresPermissions("algs:model:list")
    public R list(@RequestParam Map<String, Object> params){
        //只有超级管理员，才能查看所有模板列表
        //先这样写，之后去掉
        if(getUserId() != Constant.SUPER_ADMIN){
            params.put("createUserId", getUserId());
        }
        PageUtils page = algsModelsService.queryPageOnUse(params);

        return R.ok().put("page", page);
    }

    /**
     * Description:获取所有算法信息，用于创建算法时的下拉选框
     * @param params
     * @return
     */
    @GetMapping("/listAll")
    public R listAll(@RequestParam Map<String, Object> params){
        if(getUserId() != Constant.SUPER_ADMIN){
            params.put("createUserId", getUserId());
        }
        List<AlgorithmModel_Vo> listAll=algsModelsService.listAll(params);
        return R.ok().put("list",listAll);
    }

    /**
     * 信息
     */
    @GetMapping("/info/{modelId}")
    @RequiresPermissions("algs:template:info")
    public R info(@PathVariable("modelId") Long modelId) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidResponseException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InternalException {
        AlgorithmModel model = algsModelsService.getById(modelId);
//        Long categoryId = algsTemplsService.querycategoryId(tmpId);
//        temp.setCategoryId((categoryId));

//        不需要获取创建人的信息，总的列表中已经有了
//        String username = userService.getById(temp.getUid()).getUsername();
        List<FileTest> list=MinIoUtils.listFiles("algmodel","model"+modelId);
        return R.ok().put("model", model).put("fileList",list);
    }

    /**
     * 保存
     */
    @SysLog("保存算法模型")
    @PostMapping("/save")
    @RequiresPermissions("algs:template:save")
    public R save(MultipartHttpServletRequest request) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidResponseException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InternalException {
        AlgorithmModel model=new AlgorithmModel();
        model.setModelName(request.getParameter("modelName"));
        model.setCategoryId(Long.parseLong(request.getParameter("categoryId")));
        model.setRemark(request.getParameter("remark"));
        model.setUid(Long.parseLong(request.getParameter("uid")));
        model.setIsApprovaled((byte) 1);
        ValidatorUtils.validateEntity(model, AddGroup.class);
        List<AlgorithmModel> list = algsModelsService.list();
        for(AlgorithmModel algorithmModel : list){
            if(algorithmModel.getModelName().equals(model.getModelName())) return R.error("已经存在重复名称的算法");
        }
//        user.setCreateUserId(getUserId());
        algsModelsService.save(model);

        int modelId=algsModelsService.selectByModelName(request.getParameter("modelName")).getModelId();
        MultipartFile file=request.getFile("file");
        MinIoUtils.uploadMultipartFile(file,"algmodel","model"+modelId+"/"+file.getOriginalFilename());

        return R.ok();
    }

    /**
     * 修改模板
     */
    @SysLog("修改算法模型")
    @PostMapping("/update")
    @RequiresPermissions("algs:template:update")
    public R update(@RequestBody AlgorithmModel model){
        ValidatorUtils.validateEntity(model, UpdateGroup.class);

//        model.setCreateUserId(getUserId());
        algsModelsService.update(model);

        return R.ok();
    }

    /**
     * Description:获取minio中存储的算法库文件内容
     * @param modelId
     * @param fileName
     * @return
     * @throws Exception
     */
    @GetMapping("watchModelFile")
    public R watchModelFile(Long modelId,String fileName) throws Exception{
        String requestUrl= MinIoUtils.getFileUrl("algmodel","model"+modelId+"/"+fileName);
        HttpURLConnection conn=null;
        BufferedReader br=null;
        StringBuffer sbf=new StringBuffer();
        String content=null;
        try {
            URL url=new URL(requestUrl);
            conn=(HttpURLConnection) url.openConnection();

            //设置不使用缓存
            conn.setUseCaches(false);

            //设置链接超时时间,毫秒为单位
            conn.setConnectTimeout(1000);

            //设置读取超时时间，毫秒为单位
            conn.setReadTimeout(1000);

            //设置当前链接是否自动处理重定向。setFollowRedirects设置所有的链接是否自动处理重定向
            conn.setInstanceFollowRedirects(false);
            //开启链接
            conn.connect();

            br=new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
            String strContent=null;
            while ((strContent=br.readLine())!=null){
                sbf.append("\n");
                sbf.append(strContent);
            }
            sbf.delete(0,1);//目的是去掉首行换行符
            content=sbf.toString();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }finally {
            if(null!=br)    br.close();
            if(null!=conn)  conn.disconnect();
        }

        return R.ok().put("content",content);
    }

    /**
     * 删除模型
     */
    @SysLog("删除模型")
    @PostMapping("/delete")
    @RequiresPermissions("algs:model:delete")
    public R delete(@RequestBody Long[] modelIds){
        algsModelsService.deleteBatch(modelIds);

        return R.ok();
    }

    @GetMapping("/testUpload")
    public R testUpload() throws DockerException, InterruptedException {
        List<Image> list=DockerClientUtils.getImages();
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i).labels());
        }
        return R.ok();
    }
}
