{{ header }}package {{ package }};

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;

/** Centralized JSON deserialization utility for all DTOs. */
@SuppressWarnings("checkstyle:LineLength")
public final class JsonUtil {
    private static final ObjectMapper MAPPER;

    static {
        MAPPER = new ObjectMapper()
            .registerModule(new Jdk8Module())
            .findAndRegisterModules()
            .setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
    }

    private JsonUtil() {
        // Utility class; no instances
    }

    /**
     * Deserialize a JSON string into the given class.
     *
     * @param <T> The target type
     * @param json JSON string with Rust-side field names (snake_case)
     * @param targetClass The class to deserialize into
     * @return The deserialized instance
     * @throws {{ main_class }}Exception if deserialization fails
     */
    public static <T> T fromJson(final String json, final Class<T> targetClass) throws {{ main_class }}Exception {
        try {
            return MAPPER.readValue(json, targetClass);
        } catch (Exception e) {
            throw new {{ main_class }}Exception(
                "Failed to parse " + targetClass.getSimpleName() + " from JSON: " + e.getMessage(),
                e
            );
        }
    }
}
