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

import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.*;
import io.minio.http.Method;
import io.renren.common.utils.MinIoUtils;
import io.renren.common.utils.R;
import io.renren.modules.sys.entity.algs.FileTest;
import io.renren.modules.sys.service.FileTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import io.minio.messages.Item;
import io.minio.Result;


import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/minio")
public class MinioController {
    @Value("${minio.endpoint}")
    String endpoint;

    @Value("${minio.access-key}")
    String access_key;

    @Value("${minio.secret-key}")
    String secret_key;

    @Value("${minio.bucket}")
    String buctek;

    @Value("${tempFileLocation}")
    String tempFileLocation;

    @Autowired
    FileTestService fileTestService;




    @PostMapping("/upload")
    public void upload(@RequestParam("file")MultipartFile file) throws Exception {

        // 使用MinIO服务的URL，端口，Access key和Secret key创建一个MinioClient对象
        MinioClient minioClient = new MinioClient(endpoint, access_key, secret_key);

        // 检查存储桶是否已经存在
        boolean isExist = minioClient.bucketExists(buctek);
        if(isExist) {
            System.out.println("Bucket already exists.");
        }else {
            // 创建一个名为asiatrip的存储桶，用于存储照片的zip文件。
            minioClient.makeBucket(buctek);
        }

        // 使用putObject上传一个文件到存储桶中。
        String a = file.getOriginalFilename() ;//.split("\\.")[1];
        PutObjectOptions putObjectOptions = new PutObjectOptions(file.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);
        putObjectOptions.setContentType(file.getContentType());
        minioClient.putObject(buctek, UUID.randomUUID().toString()+"$"+a,file.getInputStream(),putObjectOptions);
        System.out.println("-----------------");

    }

    @GetMapping("/download")
    public String download() throws Exception{ //String buctek,String objectName        ResponseEntity
        // 使用MinIO服务的URL，端口，Access key和Secret key创建一个MinioClient对象
        MinioClient minioClient = new MinioClient(endpoint, access_key, secret_key);
        String buctek="test";
        String objectName="1C8EL8QQCUAUHKI31DPBTD7TJT.jpg";
        System.out.println(buctek);
        System.out.println(objectName);
//        InputStream object = minioClient.getObject(buctek, objectName);

        String objectUrl = minioClient.getObjectUrl(buctek, objectName);
        //返回Minio提供的下载链接，第四个参数是second，要给很多秒
        String presignedObjectUrl = minioClient.getPresignedObjectUrl(Method.GET, buctek, objectName, 1000, null);

        System.out.println(objectUrl);

        System.out.println(presignedObjectUrl);
        System.out.println("********");

        return presignedObjectUrl;
    }

    @GetMapping("listtest")
    public R listtest() throws Exception{

            /* play.min.io for test and development. */
            MinioClient minioClient =
                    new MinioClient(
                            endpoint,
                            access_key,
                            secret_key);

            /* Amazon S3: */
            // MinioClient minioClient = new MinioClient("https://s3.amazonaws.com", "YOUR-ACCESSKEYID",
            //                                           "YOUR-SECRETACCESSKEY");

            // Check whether 'my-bucketname' exist or not.
            boolean found = minioClient.bucketExists(buctek);
            if (found) {
                List<Item> res = new ArrayList<>();
                // List objects from 'my-bucketname'
                Iterable<Result<Item>> myObjects = minioClient.listObjects(buctek,"");
                for (Result<Item> result : myObjects) {
                    Item item = result.get();
                    if(!item.isDir())
                    System.out.println(item.lastModified() + ", " + item.size() + ", " + item.objectName());
                    res.add(item);
                }
                return R.ok().put("res", res);
            } else {
                System.out.println("bucket does not exist");
                return R.error("bucket does not exist");
            }

    }

    /**
     * Description 获取minio中指定代码文件的内容
     * @return
     */
    @GetMapping("/readUrlContent")
    public String readUrlContent(String algorithmNameToVersion,String verisionToFile,String fileName) throws Exception {


        //String requestUrl = minioClient.getPresignedObjectUrl(Method.GET, bucket, fileName, 1000, null);
        //使用minio工具类获取指定文件url
        String requestUrl= MinIoUtils.getFileUrl("algorithm","alg"+algorithmNameToVersion+"/version"+verisionToFile+"/"+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 content;
    }

    /**
     * Description 获取minio中指定传统算法代码文件的内容
     * @return
     */
    @GetMapping("/readTraUrlContent")
    public String readTraUrlContent(String algorithmNameToVersion,String fileName) throws Exception {


        //String requestUrl = minioClient.getPresignedObjectUrl(Method.GET, bucket, fileName, 1000, null);
        //使用minio工具类获取指定文件url
        String requestUrl= MinIoUtils.getFileUrl("algorithm","alg"+algorithmNameToVersion+"/"+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 content;
    }

    /**
     * Description 将codemirror中的内容写入文件
     * @return
     * @throws IOException
     */
    @PostMapping("/writeFile")
    public String writeFile(@RequestBody HashMap<String,String> map){
        File file=new File(tempFileLocation);
        try {
            //判断是否存在指定文件夹 不存在则创建
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            //判断是否存在指定文件 不存在则创建
            if(!file.exists()){
                file.createNewFile();
            }
            FileWriter fileWriter=new FileWriter(file.getAbsoluteFile());
            BufferedWriter bufferWriter = new BufferedWriter(fileWriter);
            bufferWriter.write(map.get("content"));
            bufferWriter.close();
            PutObjectOptions options=new PutObjectOptions(file.length(),PutObjectOptions.MIN_MULTIPART_SIZE);
            //使用minio工具类上传本地文件到minio
            String algorithmNameToVersion=map.get("algorithmNameToVersion");
            String verisionToFile=map.get("verisionToFile");
            String fileName=map.get("fileName");
            MinIoUtils.uploadLocalFile("algorithm", "alg"+algorithmNameToVersion+"/version"+verisionToFile+"/"+fileName,tempFileLocation,options);
        }catch (Exception e){
            e.printStackTrace();
        }

        return "success";
    }

    /**
     * Description 将codemirror中的内容写入传统算法文件
     * @return
     * @throws IOException
     */
    @PostMapping("/writeTraFile")
    public String writeTraFile(@RequestBody HashMap<String,String> map){
        File file=new File(tempFileLocation);
        try {
            //判断是否存在指定文件夹 不存在则创建
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            //判断是否存在指定文件 不存在则创建
            if(!file.exists()){
                file.createNewFile();
            }
            FileWriter fileWriter=new FileWriter(file.getAbsoluteFile());
            BufferedWriter bufferWriter = new BufferedWriter(fileWriter);
            bufferWriter.write(map.get("content"));
            bufferWriter.close();
            PutObjectOptions options=new PutObjectOptions(file.length(),PutObjectOptions.MIN_MULTIPART_SIZE);
            //使用minio工具类上传本地文件到minio
            String algorithmNameToVersion=map.get("algorithmNameToVersion");
            String fileName=map.get("fileName");
            MinIoUtils.uploadLocalFile("algorithm", "alg"+algorithmNameToVersion+"/"+fileName,tempFileLocation,options);
        }catch (Exception e){
            e.printStackTrace();
        }

        return "success";
    }

    /**
     * 根据传入的algId与versionId以及fileName 删除文件
     * @param
     * @return
     */
    @GetMapping("/deleteFile")
    public R deleteFile(String algorithmNameToVersion,String versionToFile,String fileName) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InsufficientDataException, InternalException {
        System.out.println("alg"+algorithmNameToVersion+"/version"+versionToFile+"/"+fileName);
        MinIoUtils.deleteFile("algorithm","alg"+algorithmNameToVersion+"/version"+versionToFile+"/"+fileName);
        return R.ok();
    }
}
