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

import io.minio.errors.*;
import io.renren.common.annotation.SysLog;
import io.renren.common.utils.Constant;
import io.renren.common.utils.MinIoUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;
import io.renren.common.validator.ValidatorUtils;
import io.renren.common.validator.group.AddGroup;
import io.renren.common.validator.group.UpdateGroup;
import io.renren.modules.app.service.UserService;
import io.renren.modules.sys.controller.AbstractController;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.algs.AlgorithmTemplate;
import io.renren.modules.sys.entity.algs.AlgorithmTemplate_Vo;
import io.renren.modules.sys.entity.algs.CategoryEntity;
import io.renren.modules.sys.entity.algs.FileTest;
import io.renren.modules.sys.service.AlgsTemplsService;
import io.renren.modules.sys.service.CategoryService;
import org.apache.commons.lang.ArrayUtils;
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;

/**
 * @Author: Ivan Q
 * @Date: 2021/5/25 15:03
 */
@RestController
@RequestMapping("/algs/templs")
public class algTemplsController extends AbstractController {
    @Autowired
    private AlgsTemplsService algsTemplsService;

    @Autowired
    private CategoryService categoryService;


    /**
     * 所有模板列表
     * 此方法不再使用了
     */
    @GetMapping("/listnotuse")
    public R listNotUse(@RequestParam Map<String, Object> params){
        //只有超级管理员，才能查看所有模板列表
        //先这样写，之后去掉
        if(getUserId() != Constant.SUPER_ADMIN){
            params.put("createUserId", getUserId());
        }
        PageUtils page = algsTemplsService.queryPage(params);

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

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

    /**
     * 删除模板
     */
    @SysLog("删除模板")
    @PostMapping("/delete")
    @RequiresPermissions("algs:template:delete")
    public R delete(@RequestBody Long[] tmpIds){
        algsTemplsService.deleteBatch(tmpIds);

        return R.ok();
    }

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

//        不需要获取创建人的信息，总的列表中已经有了
//        String username = userService.getById(temp.getUid()).getUsername();

        //获取模板文件名
        List<FileTest> list=MinIoUtils.listFiles("algtemplate","template"+tmpId);

        return R.ok().put("temp", temp).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 {

        AlgorithmTemplate template=new AlgorithmTemplate();
        template.setTmpName(request.getParameter("tmpName"));
        template.setCategoryId(Long.parseLong(request.getParameter("categoryId")));
        template.setRemark(request.getParameter("remark"));
        template.setUid(Long.parseLong(request.getParameter("uid")));
        ValidatorUtils.validateEntity(template, AddGroup.class);
        List<AlgorithmTemplate> list = algsTemplsService.list();
        for(AlgorithmTemplate algorithmTemplate : list){
            if(algorithmTemplate.getTmpName().equals(template.getTmpName())) return R.error("已经存在重复名称的模板");
        }
//        user.setCreateUserId(getUserId());
        algsTemplsService.save(template);


        Long temId=algsTemplsService.selectByTmpName(request.getParameter("tmpName")).getTmpId();

        List<MultipartFile> files=request.getFiles("file");
        for(MultipartFile file:files){
            if(file.isEmpty())  break;
            MinIoUtils.uploadMultipartFile(file,"algtemplate","template"+temId+"/"+file.getOriginalFilename());
        }
        //MinIoUtils.uploadMultipartFile(file,"algtemplate","template"+temId+"/"+file.getOriginalFilename());


        return R.ok();
    }

    /**
     * 修改模板
     */
    @SysLog("修改模板")
    @PostMapping("/update")
    @RequiresPermissions("algs:template:update")
    public R update(MultipartHttpServletRequest request){
        AlgorithmTemplate tmp=new AlgorithmTemplate();
        tmp.setTmpName(request.getParameter("tmpName"));
        tmp.setCategoryId(Long.parseLong(request.getParameter("categoryId")));
        tmp.setRemark(request.getParameter("remark"));
        tmp.setUid(Long.parseLong(request.getParameter("uid")));
        tmp.setTmpId(Long.parseLong(request.getParameter("tmpId")));
        ValidatorUtils.validateEntity(tmp, UpdateGroup.class);
        List<AlgorithmTemplate> list = algsTemplsService.list();
        for(AlgorithmTemplate algorithmTemplate : list){
            if(algorithmTemplate.getTmpName().equals(tmp.getTmpName())&&algorithmTemplate.getTmpId()!=tmp.getTmpId()) return R.error("已经存在重复名称的模板");
        }

        algsTemplsService.update(tmp);

        return R.ok();
    }

    /**
     * Description:获取minio中存储的模板文件内容
     * @param temId 模板id
     * @return
     */
    @GetMapping("/watchTemFile")
    public R watchTemFile(Long temId,String fileName) throws Exception{
        String requestUrl= MinIoUtils.getFileUrl("algtemplate","template"+temId+"/"+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);
    }

    /**
     * Description:获取python读取kafka实时数据的模板
     * @return
     */
    @GetMapping("/getPythonKafkaTmp")
    public R getPythonKafkaTmp(){
        String kafkaString="from kafka import KafkaConsumer\n" +
                "\n" +
                "consumer = KafkaConsumer(bootstrap_servers=['192.168.25.102:9092'])\n" +
                "consumer.subscribe(topics=topics)\n" +
                "\n" +
                "for message in consumer:\n" +
                "    print(\"topic:%s partition:%d offset:%d: key=%s value=%s\" % (message.topic, message.partition,message.offset, message.key,message.value))\n";
        String b="topics=('test')";
        StringBuilder sb=new StringBuilder(b);
        int index=sb.indexOf(")");
        sb.insert(index,",'test0'");
        b=sb.toString();
        String result=b+"\n"+kafkaString;
        return R.ok().put("code",result);
    }




}
