package com.banesco.common.domain.dto.bian.device;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JsonHelper {

    private static final Logger logger = Logger.getLogger(JsonHelper.class.getName());
    public static final ObjectMapper MAPPER = new ObjectMapper();

    static {
        MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * Convert Object to jsonString
     *
     * @param object El objeto a convertir en JSON.
     * @return La cadena JSON resultante o null si ocurre un error.
     */
    public static String getJsonFromObject(Object object) {
        if (object == null) {
            return "null";
        }
        try {
            return MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            logger.log(Level.SEVERE, "Error parsing objeto a JSON: {0}", e.getMessage());
            return null;
        }
    }

    /**
     * Convierte una cadena JSON en un objeto Java de la clase especificada.
     *
     * @param json      La cadena JSON a convertir.
     * @param className La clase del objeto Java resultante.
     * @param <T>       El tipo del objeto resultante.
     * @return El objeto Java resultante, o null si ocurre un error o la cadena
     * JSON está vacía.
     */
    public static <T> T getObjectFromJson(String json, Class<T> className) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        try {
            return MAPPER.readValue(json, className);
        } catch (JsonProcessingException | IllegalArgumentException e) {
            logger.log(Level.WARNING, "Error parsing JSON a objeto: {0}", e.getMessage());
            return null;
        }
    }

    public static <T> List<T> getListFromJson(String json, Class<T> className) {
        if (json == null || json.isEmpty()) {
            return new ArrayList<>();
        }
        try {
            return MAPPER.readValue(json,
                    MAPPER.getTypeFactory().constructCollectionType(List.class, className)
            );
        } catch (JsonProcessingException | IllegalArgumentException e) {
            logger.log(Level.WARNING, "Error parsing JSON a List Object: {0}", e.getMessage());
        }

        return new ArrayList<>();
    }

    public static <T> List<T> getListFromInputStream(InputStream inputStream, Class<T> className) throws IOException {
        if (inputStream == null) {
            return new ArrayList<>();
        }
        try {
            return MAPPER.readValue(inputStream,
                    MAPPER.getTypeFactory().constructCollectionType(List.class, className)
            );
        } catch (JsonProcessingException | IllegalArgumentException e) {
            logger.log(Level.WARNING, "Error parsing JSON a List Object: {0}", e.getMessage());
        }

        return new ArrayList<>();
    }
}
