package cz.moneta.test.harness.support.messaging.kafka;

import net.javacrumbs.jsonunit.assertj.JsonAssert;

/**
 * Interface representing the response from a message receive operation.
 * Provides fluent assertion methods for testing received messages.
 */
public interface MessageResponse {

    /**
     * Asserts that a field has the expected value.
     *
     * @param path    JSON path or XPath
     * @param value   expected value as string
     * @return this for chaining
     */
    MessageResponse andAssertFieldValue(String path, String value);

    /**
     * Asserts that a field is present.
     *
     * @param path JSON path or XPath
     * @return this for chaining
     */
    MessageResponse andAssertPresent(String path);

    /**
     * Asserts that a field is not present.
     *
     * @param path JSON path or XPath
     * @return this for chaining
     */
    MessageResponse andAssertNotPresent(String path);

    /**
     * Asserts that a header has the expected value.
     *
     * @param headerName name of the header
     * @param value      expected value
     * @return this for chaining
     */
    MessageResponse andAssertHeaderValue(String headerName, String value);

    /**
     * Asserts that the body contains a substring.
     * Useful for EBCDIC/UTF-8 raw text messages.
     *
     * @param substring expected substring
     * @return this for chaining
     */
    MessageResponse andAssertBodyContains(String substring);

    /**
     * Returns AssertJ JsonAssert for complex assertions.
     *
     * @return JsonAssert instance
     */
    JsonAssert.ConfigurableJsonAssert andAssertWithAssertJ();

    /**
     * Extracts a value from the message body.
     *
     * @param path JSON path or XPath
     * @return JsonPathValue wrapper for further conversion
     */
    JsonPathValue extract(String path);

    /**
     * Deserializes the message body to a Java object.
     *
     * @param type the target type
     * @param <T>  the target type
     * @return deserialized object
     */
    <T> T mapTo(Class<T> type);

    /**
     * Gets the underlying received message.
     *
     * @return the received message
     */
    ReceivedMessage getMessage();

    /**
     * Gets the message body as string.
     *
     * @return body string
     */
    String getBody();

    /**
     * Gets a header value.
     *
     * @param name header name
     * @return header value or null
     */
    String getHeader(String name);

    /**
     * Interface for extracted path values.
     */
    interface JsonPathValue {
        /**
         * Converts to string.
         *
         * @return string value
         */
        String asText();

        /**
         * Converts to integer.
         *
         * @return integer value
         */
        Integer asInt();

        /**
         * Converts to long.
         *
         * @return long value
         */
        Long asLong();

        /**
         * Converts to boolean.
         *
         * @return boolean value
         */
        Boolean asBoolean();

        /**
         * Checks if value is missing/null.
         *
         * @return true if value is missing
         */
        boolean isMissing();
    }
}
