/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.common.serializer.json;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.yami.shop.common.bean.Qiniu;
import com.yami.shop.common.util.ImgUploadUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 图片JSON序列化器类
 * 该类实现了`JsonSerializer<String>`接口，用于自定义对字符串类型的图片相关数据进行JSON序列化的逻辑。
 * 主要功能是根据图片的上传类型以及是否已经是完整的URL等情况，对传入的图片字符串（可能是多个图片路径用逗号分隔的形式）进行处理，
 * 将其转换为合适的格式后再进行JSON序列化，确保在序列化后的JSON数据中图片路径是符合要求且可正确访问的形式。
 *
 * @author lanhai
 */
@Component
// 使用 @Component 注解将该类注册为Spring容器中的一个组件，方便进行依赖注入等操作
public class ImgJsonSerializer extends JsonSerializer<String> {

    @Autowired
    // 通过依赖注入获取Qiniu对象，该对象可能包含与七牛云相关的配置信息，比如七牛云资源的URL等，用于处理图片相关逻辑
    private Qiniu qiniu;
    @Autowired
    // 通过依赖注入获取ImgUploadUtil对象，该工具类可能用于获取图片上传的相关路径、类型等信息，辅助图片处理逻辑
    private ImgUploadUtil imgUploadUtil;

    /**
     * 重写的序列化方法
     * 该方法实现了对传入的字符串类型的图片数据进行具体的序列化处理逻辑。
     * 首先判断传入的字符串是否为空，如果为空则直接写入空字符串到JSON生成器中；然后根据图片上传类型确定资源URL，
     * 接着对字符串中可能包含的多个图片路径（以逗号分隔）进行遍历处理，判断是否已经是完整的URL，如果是则直接添加，否则添加对应的资源URL前缀后再添加，
     * 最后将处理后的字符串写入JSON生成器中完成序列化。
     *
     * @param value 要进行序列化的字符串数据，通常是表示图片路径的字符串，可能是单个路径也可能是多个路径用逗号分隔的形式。
     * @param gen JSON生成器对象，用于将处理后的字符串数据按照JSON格式规则写入到最终的JSON输出中，实现序列化操作。
     * @param serializers 序列化器提供者对象，用于获取序列化相关的配置等信息，在这里主要是配合整个序列化流程的上下文环境。
     * @throws IOException 如果在向JSON生成器写入数据过程中出现I/O异常（比如写入文件错误等情况），则会抛出该异常，向上传播到调用者进行处理。
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 判断传入的字符串是否为空（空白字符串，包含空字符串、全是空格等情况），如果为空则直接写入空字符串到JSON生成器中，并结束当前方法执行
        if (StrUtil.isBlank(value)) {
            gen.writeString(StrUtil.EMPTY);
            return;
        }

        // 将传入的字符串按照逗号进行分割，得到一个包含各个图片路径的字符串数组，假设传入的字符串格式是多个图片路径用逗号分隔的形式
        String[] imgs = value.split(StrUtil.COMMA);
        StringBuilder sb = new StringBuilder();
        String resourceUrl = "";
        String rule = "^((http[s]{0,1})://)";
        Pattern pattern = Pattern.compile(rule);

        // 根据图片上传工具类中获取的上传类型来确定资源URL，如果上传类型是2，可能表示使用七牛云存储，从Qiniu对象中获取资源URL
        if (Objects.equals(imgUploadUtil.getUploadType(), 2)) {
            resourceUrl = qiniu.getResourcesUrl();
        } 
        // 如果上传类型是1，可能表示使用其他本地或指定的存储方式，从ImgUploadUtil对象中获取对应的资源URL
        else if (Objects.equals(imgUploadUtil.getUploadType(), 1)) {
            resourceUrl = imgUploadUtil.getResourceUrl();
        }

        // 遍历分割后的图片路径字符串数组，对每个图片路径进行处理
        for (String img : imgs) {
            Matcher matcher = pattern.matcher(img);
            // 使用正则表达式匹配器判断图片路径是否已经是以http或https开头（即是否已经是完整的URL形式），如果是则直接添加到结果字符串构建器中，并添加逗号作为分隔（后续会删除最后一个多余的逗号）
            if (matcher.find()) {
                sb.append(img).append(StrUtil.COMMA);
            } else {
                // 如果图片路径不是完整的URL形式，则添加之前确定好的资源URL前缀，再添加图片路径本身，然后添加逗号作为分隔，构建完整的可访问的图片路径形式
                sb.append(resourceUrl).append(img).append(StrUtil.COMMA);
            }
        }

        // 删除最后一个多余的逗号（因为在循环中每次添加路径后都添加了逗号，最后一个逗号是多余的）
        sb.deleteCharAt(sb.length() - 1);

        // 将处理好的完整图片路径字符串写入到JSON生成器中，完成对图片相关字符串的JSON序列化操作
        gen.writeString(sb.toString());
    }
}