package enea.lecservice.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

@Log4j2
public class JacksonUtils {
    public static String toJson(Object object) {
        String result = null;
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            result = objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            log.info(String.format("Errore durante la conversione in JSON:\n %s ", stackTraceToString(e)));
        }

        return result;
    }

    public static <T> T fromJson(String json, TypeReference<T> type) {
        T result = null;
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
        try {
            result = objectMapper.readValue(json, type);
        }
        catch (Exception ex) {
            ex.printStackTrace();
            log.info(String.format("Errore durante la conversione in JSON:\n %s ", stackTraceToString(ex)));
        }

        return result;
    }

    public static <T> T fromJson(Class<T> cls, String json, Class... registerSubtypesClasses) {
        ObjectMapper jsonMapper = Jackson2ObjectMapperBuilder.json().build();

        T obj = null;
        try {
            if (registerSubtypesClasses != null)
                jsonMapper.registerSubtypes(registerSubtypesClasses);
            obj = jsonMapper.readValue(json, cls);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return obj;
    }

    public static <T> String toJson(T obj, Class... registerSubtypesClasses) {
        ObjectMapper jsonMapper = Jackson2ObjectMapperBuilder.json().build();
        String serializedSchema = null;
        try {
            if (registerSubtypesClasses != null)
                jsonMapper.registerSubtypes(registerSubtypesClasses);
            serializedSchema = jsonMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return serializedSchema;
    }

    public static String stackTraceToString(Throwable e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }
}
