// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/encdec/DecodingContext.java
// @RequiredArgsConstructor @Getter
// public class DecodingContext {
// 
//     private final long contentLength;
//     private final String contentType;
//     private final String characterEncoding;
//     private final DecoderChain decoderChain;
// }


import io.github.cjstehno.ersatz.encdec.DecodingContext;
import org.hamcrest.Matcher;
import java.util.function.BiFunction;
import static org.hamcrest.Matchers.equalTo;

/**
 * Copyright (C) 2022 Christopher J. Stehno
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.github.cjstehno.ersatz.cfg;




/**
 * Expectation configuration for a request with body content.
 */
public interface RequestWithContent extends Request {

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Object body, String contentType) {
        return body(body instanceof Matcher ? (Matcher<Object>) body : equalTo(body), contentType);
    }

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content matcher
     * @param contentType the body content type
     * @return a reference to this request
     */
    RequestWithContent body(final Matcher<Object> body, String contentType);

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Object body, ContentType contentType) {
        return body(body, contentType.getValue());
    }

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content matcher
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Matcher<Object> body, ContentType contentType) {
        return body(body, contentType.getValue());
    }

    /**
     * Specifies a custom body content converter function. The function will have the client request body content as a byte array and it will be
     * converted into the specified output type. Generally the conversion is used when comparing the client request with the configured request
     * body expectation.
     *
     * @param contentType the content type that the convert will handle
     * @param decoder     the conversion function
     * @return a reference to this request
     */

// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/encdec/DecodingContext.java
// @RequiredArgsConstructor @Getter
// public class DecodingContext {
// 
//     private final long contentLength;
//     private final String contentType;
//     private final String characterEncoding;
//     private final DecoderChain decoderChain;
// }


// Path: ersatz/src/main/java/io/github/cjstehno/ersatz/cfg/RequestWithContent.java
import io.github.cjstehno.ersatz.encdec.DecodingContext;
import org.hamcrest.Matcher;
import java.util.function.BiFunction;
import static org.hamcrest.Matchers.equalTo;

/**
 * Copyright (C) 2022 Christopher J. Stehno
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.github.cjstehno.ersatz.cfg;




/**
 * Expectation configuration for a request with body content.
 */
public interface RequestWithContent extends Request {

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Object body, String contentType) {
        return body(body instanceof Matcher ? (Matcher<Object>) body : equalTo(body), contentType);
    }

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content matcher
     * @param contentType the body content type
     * @return a reference to this request
     */
    RequestWithContent body(final Matcher<Object> body, String contentType);

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Object body, ContentType contentType) {
        return body(body, contentType.getValue());
    }

    /**
     * Configures the expected body content of the request with the specified content type.
     *
     * @param body        the body content matcher
     * @param contentType the body content type
     * @return a reference to this request
     */
    default RequestWithContent body(final Matcher<Object> body, ContentType contentType) {
        return body(body, contentType.getValue());
    }

    /**
     * Specifies a custom body content converter function. The function will have the client request body content as a byte array and it will be
     * converted into the specified output type. Generally the conversion is used when comparing the client request with the configured request
     * body expectation.
     *
     * @param contentType the content type that the convert will handle
     * @param decoder     the conversion function
     * @return a reference to this request
     */

    RequestWithContent decoder(final String contentType, final BiFunction<byte[], DecodingContext, Object> decoder);
