package io.renren.modules.kubesphere.service;

import com.google.gson.JsonObject;
import io.renren.common.utils.GsonUtil;
import io.renren.modules.kubesphere.config.KubeSphereConfig;
import io.renren.modules.kubesphere.interceptor.KubeSphereTokenInterceptor;
import io.renren.modules.kubesphere.module.KubeSphereRequestBuilder;
import io.renren.modules.kubesphere.module.response.S2iBuilderCreateBinaryResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 镜像制作服务,包含了将制作好的镜像上传到私人harbor仓库
 *
 * @author chenrj
 * @email 1412736935@qq.com
 * @since 2021/7/29
 */

@Service
public class S2iService {

    private final RestTemplate restTemplate;

    @Autowired
    public S2iService(RestTemplate restTemplate) {
        // 设置Token 等信息
        restTemplate.getInterceptors().add(new KubeSphereTokenInterceptor());
        this.restTemplate = restTemplate;
    }

    public String s2iBuilder(String jsonData) {
        System.out.println("jsonData:" + jsonData);
        Map<String, Object> parameter = GsonUtil.convertJsonToMap(jsonData);
        String languageType = parameter.get("languageType").toString();
        String fileName = parameter.get("fileName").toString();
        String fileSize = parameter.get("fileSize").toString();
        String creator = parameter.get("creator").toString();
        String namespace = parameter.get("namespace").toString();
        String tag = parameter.get("tag").toString();
        String builderImage = parameter.get("builderImage").toString();
        String runtimeImage = parameter.get("runtimeImage").toString();
        String type = parameter.get("type").toString();
        String imageName = parameter.get("imageName").toString();
        String warehouse = parameter.get("warehouse").toString();
        String sourceUrl = parameter.get("sourceUrl").toString();
        String formatImageName = formatImageName(imageName, tag);
        // JsonArray jsonArray = GsonUtil.convertJsonArray(parameter.get("environment").toString());
        // String environment = jsonArray.toString();
        // environment = environment.substring(1, environment.length() - 1);
        String request = String.format(KubeSphereRequestBuilder.S2iBuilder, languageType, fileName, fileSize, creator, formatImageName, namespace,
                tag, builderImage, runtimeImage, type, imageName, warehouse, sourceUrl);
        System.out.println("s2iBuilder请求体" + request);
        Map<String, Object> hashmap = GsonUtil.convertJsonToMap(request);
        ResponseEntity<String> s2ires = restTemplate.postForEntity(KubeSphereConfig.URL.S2I_BUILDER_URL, hashmap, String.class);
        // 换一种response
        // Map<String, Object> hashmap = GsonUtil.convertJsonToMap(String.format(s2i, sourceUrl));
        // KubeSphereRequestBuilder.buildS2iRequest(sourceUrl)
        // ResponseEntity<S2iBuildersResponse> s2ires = restTemplate.postForEntity(KubeSphereConfig.URL.S2I_QUERY_URL, hashmap, S2iBuildersResponse.class);

        // 另一种方法
        // KubeSphereRequestBuilder.buildS2iRequest(sourceUrl)
        // ResponseEntity<S2iBuildersResponse> s2ires = restTemplate.postForEntity(KubeSphereConfig.URL.S2I_QUERY_URL, KubeSphereRequestBuilder.buildS2iRequest(sourceUrl), S2iBuildersResponse.class);
        // 获取响应主体
        if (s2ires.getBody() != null) {
            return s2iRun(formatImageName, namespace, creator);
        } else return null;
    }

    /**
     * s2iRun ,构建镜像后自动上传harbor仓库
     * <p>
     * s2irun
     *
     * @param formatImageName
     * @param namespace
     * @param creator
     * @return
     */
    public String s2iRun(String formatImageName, String namespace, String creator) {
        String formatS2iRunPodName = formatS2iRunPodName(formatImageName);
        String jsonData = String.format(KubeSphereRequestBuilder.S2iRun, formatS2iRunPodName, namespace, creator, formatImageName);
        System.out.println("s2iRun请求体" + jsonData);
        Map<String, Object> argument = GsonUtil.convertJsonToMap(jsonData);
        ResponseEntity<String> s2ires = restTemplate.postForEntity(KubeSphereConfig.URL.S2I_RUN, argument, String.class);
        return s2ires.getBody().toString();
    }

    /**
     * 创建文件目录
     *
     * @param fileName
     * @return
     */
    public String s2iCreateBinary(String fileName) {
        // KubeSphereRequestBuilder.buildS2iCreateBinaryRequest(fileName)
        String request = String.format(KubeSphereRequestBuilder.S2iBuilderCreateBinary, fileName);
        System.out.println("s2iCreateBinary请求体：" + request);
        Map<String, String> map = GsonUtil.convertJsonToMap(request);
        // GsonUtil.convertJsonToMap(String.format(KubeSphereRequestBuilder.S2iBuilderCreateBinary, fileName))
        ResponseEntity<S2iBuilderCreateBinaryResponse> s2iBuildersResponseResponseEntity =
                restTemplate.postForEntity(KubeSphereConfig.URL.S2I_CREATE_BINARY_QUERY_URL,
                        map, S2iBuilderCreateBinaryResponse.class);
        return s2iBuildersResponseResponseEntity.getBody().toString();
    }

    /**
     * 向kubesphere上传文件
     *
     * @param multipartFile
     * @return
     * @throws IOException
     */
    public String uploadFile(MultipartFile multipartFile) throws IOException {
        String fileName = multipartFile.getOriginalFilename();

        String formatFileName = formatFileName(fileName);
        s2iCreateBinary(formatFileName);
        ByteArrayResource fileAsResource = new ByteArrayResource(multipartFile.getBytes()) {
            @Override
            public String getFilename() {
                return fileName;
            }

            @Override
            public long contentLength() {
                return multipartFile.getSize();
            }
        };
        MultiValueMap<String, Object> multipartRequest = new LinkedMultiValueMap<>();
        multipartRequest.add("s2ibinary", fileAsResource);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity(multipartRequest, headers);
        String request = String.format(KubeSphereConfig.URL.S2I_UPLOAD_FILE_QUERY_URL, formatFileName);
        System.out.println("uploadFile请求体：" + request);
        ResponseEntity<String> responseEntity = restTemplate.exchange(request, HttpMethod.PUT, requestEntity, String.class);
        return responseEntity.getBody().toString();
    }

    /**
     * 格式化file名字，会追加随机4位，避免重复
     *
     * @param fileName
     * @return
     */
    private String formatFileName(String fileName) {
        fileName = fileName.toLowerCase().replaceAll("[^(a-zA-Z0-9)]", "-") + randomlyGenerateCharacters(4);
        return fileName;
    }

    /**
     * 随机生成n位的36进制字符串
     *
     * @param n
     * @return
     */
    public String randomlyGenerateCharacters(int n) {
        Random random = new Random();
        String res = "";
        for (int i = 0; i < n; i++) {
            int rand = random.nextInt(36);
            if (rand < 10) {
                res += (char) ('0' + rand);
            } else {
                res += (char) ('a' + (rand - 10));
            }
        }
        return res;
    }

    /**
     * 格式化镜像名字
     *
     * @param imageName
     * @param tag
     * @return
     */
    private String formatImageName(String imageName, String tag) {
        String res = "";
        res = imageName.toLowerCase() + "-" + tag + "-" + randomlyGenerateCharacters(3);
        return res;
    }

    /**
     * 格式化s2irunpod名字
     *
     * @param builderImageName
     * @return
     */
    private String formatS2iRunPodName(String builderImageName) {
        String res = "";
        res = builderImageName.toLowerCase() + "-" + randomlyGenerateCharacters(3);
        return res;
    }

    /**
     * args 获取
     */
    public HashMap<String, String> getArgs(String uploadFileResponse) {
        HashMap<String, String> args = new HashMap<>();
        JsonObject jsonObject = GsonUtil.convertJsonObject(uploadFileResponse);
        String spec = jsonObject.get("spec").toString();
        JsonObject specJsonObject = GsonUtil.convertJsonObject(spec);
        String imageSize = jsonObject.get("imageSize").getAsString();
        String downloadURL = specJsonObject.get("downloadURL").getAsString();
        String imageName = specJsonObject.get("fileName").getAsString();
        args.put("imageName", imageName);
        args.put("imageSize", imageSize);
        args.put("creator", "admin");
        String tag = "latest";
        args.put("tag", tag);
        String formatImageName = formatImageName(imageName, tag);
        args.put("formatImageName", formatImageName);
        args.put("namespace", "mkcloud");
        args.put("builderImage", "registry.cn-beijing.aliyuncs.com/kubesphereio/s2i-binary:v2.1.0");
        args.put("runtimeImage", "registry.cn-beijing.aliyuncs.com/kubesphereio/java-8-runtime:v2.1.0");
        args.put("sourceUrl", downloadURL);
        args.put("warehouse", "harbor");
        return args;
    }


    public String s2iBuilder_v2(HashMap<String, String> parameter) {
        String imageName = parameter.get("imageName");
        String imageSize = parameter.get("imageSize");
        String creator = parameter.get("creator");
        String namespace = parameter.get("namespace");
        String tag = parameter.get("tag");
        String builderImage = parameter.get("builderImage");
        String runtimeImage = parameter.get("runtimeImage");
        String warehouse = parameter.get("warehouse");
        String sourceUrl = parameter.get("sourceUrl");
        String formatImageName = formatImageName(imageName, tag);

        String jsonData = String.format(KubeSphereRequestBuilder.S2iBuilder, imageName, imageSize, creator, formatImageName, namespace,
                tag, builderImage, sourceUrl, imageName, warehouse);
        System.out.println("s2iBuilder_v2_JsonData:" + jsonData);
        Map<String, Object> hashmap = GsonUtil.convertJsonToMap(jsonData);
        ResponseEntity<String> s2ires = restTemplate.postForEntity(KubeSphereConfig.URL.S2I_BUILDER_URL, hashmap, String.class);
        if (s2ires.getBody() != null) {
            return s2iRun(formatImageName, namespace, creator);
        } else return null;
    }


}
