// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you 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 org.apache.juneau.rest.mock2;

import java.util.*;

import org.apache.juneau.json.*;
import org.apache.juneau.marshall.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.client.*;
import org.apache.juneau.http.remote.*;
import org.apache.juneau.serializer.*;

/**
 * Creates a mocked interface against a REST resource class to use for creating test remote resource interfaces.
 *
 * <ul class='seealso'>
 * 	<li class='link'>{@doc juneau-rest-mock.MockRemoteResource}
 * </ul>
 *
 * @param <T> The interface class.
 */
public class MockRemoteResource<T> {

	private MockRest.Builder mrb;
	private RestClientBuilder rcb = RestClient.create().json();
	private final Class<T> intf;

	/**
	 * Constructor.
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 */
	protected MockRemoteResource(Class<T> intf, Object impl) {
		this.intf = intf;
		mrb = MockRest.create(impl);
	}

	/**
	 * Create a new builder using the specified remote resource interface and REST implementation bean or bean class.
	 *
	 * <p>
	 * Uses {@link JsonSerializer#DEFAULT} and {@link JsonParser#DEFAULT} for serializing and parsing by default.
	 *
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @return A new builder.
	 */
	public static <T> MockRemoteResource<T> create(Class<T> intf, Object impl) {
		return new MockRemoteResource<>(intf, impl);
	}

	/**
	 * Create a new builder using the specified remote resource interface and REST implementation bean or bean class.
	 *
	 * <p>
	 * Uses the serializer and parser defined on the specified marshall for serializing and parsing by default.
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @param m
	 * 	The marshall to use for serializing and parsing the HTTP bodies.
	 * @return A new builder.
	 */
	public static <T> MockRemoteResource<T> create(Class<T> intf, Object impl, Marshall m) {
		return new MockRemoteResource<>(intf, impl).marshall(m);
	}

	/**
	 * Create a new builder using the specified remote resource interface and REST implementation bean or bean class.
	 *
	 * <p>
	 * Uses the serializer and parser defined on the specified marshall for serializing and parsing by default.
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @param s
	 * 	The serializer to use for serializing request bodies.
	 * 	<br>Can be <jk>null</jk> to force no serializer to be used and no <c>Content-Type</c> header.
	 * @param p
	 * 	The parser to use for parsing response bodies.
	 * 	<br>Can be <jk>null</jk> to force no parser to be used and no <c>Accept</c> header.
	 * @return A new builder.
	 */
	public static <T> MockRemoteResource<T> create(Class<T> intf, Object impl, Serializer s, Parser p) {
		return new MockRemoteResource<>(intf, impl).serializer(s).parser(p);
	}

	/**
	 * Constructs a remote proxy interface based on the settings of this builder.
	 *
	 * @return A new remote proxy interface.
	 */
	public T build() {
		MockRest mr = mrb.build();
		return rcb.httpClientConnectionManager(new MockHttpClientConnectionManager(mr)).rootUrl("http://localhost").headers(mr.getHeaders()).build().getRemoteResource(intf);
	}

	/**
	 * Convenience method for getting a remote resource interface.
	 *
	 * <p>
	 * Uses {@link JsonSerializer#DEFAULT} and {@link JsonParser#DEFAULT} for serializing and parsing by default.
	 *
	 * <p>
	 * Equivalent to calling the following:
	 * <p class='bcode w800'>
	 * 	MockRemoteResource.<jsf>create</jsf>(intf, impl).build();
	 * </p>
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @return A new proxy interface.
	 */
	public static <T> T build(Class<T> intf, Object impl) {
		return create(intf, impl).build();
	}

	/**
	 * Convenience method for getting a remote resource interface.
	 *
	 * <p>
	 * Uses the serializer and parser defined on the specified marshall for serializing and parsing by default.
	 *
	 * <p>
	 * Equivalent to calling the following:
	 * <p class='bcode w800'>
	 * 	MockRemoteResource.<jsf>create</jsf>(intf, impl).marshall(m).build();
	 * </p>
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @param m
	 * 	The marshall to use for serializing request bodies and parsing response bodies.
	 * 	<br>Can be <jk>null</jk> to force no serializer or parser to be used and no <c>Accept</c> or <c>Content-Type</c> header.
	 * @return A new proxy interface.
	 */
	public static <T> T build(Class<T> intf, Object impl, Marshall m) {
		return create(intf, impl).marshall(m).build();
	}

	/**
	 * Convenience method for getting a remote resource interface.
	 *
	 * <p>
	 * Uses the specified serializer and parser for serializing and parsing by default.
	 *
	 * <p>
	 * Equivalent to calling the following:
	 * <p class='bcode w800'>
	 * 	MockRemoteResource.<jsf>create</jsf>(intf, impl).serializer(s).parser(p).build();
	 * </p>
	 *
	 * @param intf
	 * 	The remote interface annotated with {@link RemoteResource @RemoteResource}.
	 * @param impl
	 * 	The REST implementation bean or bean class annotated with {@link Rest @Rest}.
	 * 	<br>If a class, it must have a no-arg constructor.
	 * @param s
	 * 	The serializer to use for serializing request bodies.
	 * 	<br>Can be <jk>null</jk> to force no serializer to be used and no <c>Content-Type</c> header.
	 * @param p
	 * 	The parser to use for parsing response bodies.
	 * 	<br>Can be <jk>null</jk> to force no parser to be used and no <c>Accept</c> header.
	 * @return A new proxy interface.
	 */
	public static <T> T build(Class<T> intf, Object impl, Serializer s, Parser p) {
		return create(intf, impl).serializer(s).parser(p).build();
	}

	/**
	 * Enable debug mode.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> debug() {
		mrb.debug();
		rcb.debug();
		return this;
	}

	/**
	 * Adds a header to every request.
	 *
	 * @param name The header name.
	 * @param value
	 * 	The header value.
	 * 	<br>Can be <jk>null</jk> (will be skipped).
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> header(String name, Object value) {
		mrb.header(name, value);
		rcb.header(name, value);
		return this;
	}

	/**
	 * Adds the specified headers to every request.
	 *
	 * @param value
	 * 	The header values.
	 * 	<br>Can be <jk>null</jk> (existing values will be cleared).
	 * 	<br><jk>null</jk> null map values will be ignored.
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> headers(Map<String,Object> value) {
		mrb.headers(value);
		rcb.headers(value);
		return this;
	}

	/**
	 * Adds an <c>Accept</c> header to every request.
	 *
	 * @param value The <c>Accept</c> header value.
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> accept(String value) {
		mrb.accept(value);
		rcb.accept(value);
		return this;
	}

	/**
	 * Adds a <c>Content-Type</c> header to every request.
	 *
	 * @param value The <c>Content-Type</c> header value.
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> contentType(String value) {
		mrb.contentType(value);
		rcb.contentType(value);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/json"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> json() {
		marshall(Json.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/json+simple"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> simpleJson() {
		marshall(SimpleJson.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/xml"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> xml() {
		marshall(Xml.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/html"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> html() {
		marshall(Html.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/plain"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> plainText() {
		marshall(PlainText.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"octal/msgpack"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> msgpack() {
		marshall(MsgPack.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/uon"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> uon() {
		marshall(Uon.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"application/x-www-form-urlencoded"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> urlEnc() {
		marshall(UrlEncoding.DEFAULT);
		return this;
	}

	/**
	 * Convenience method for setting <c>Accept</c> and <c>Content-Type</c> headers to <js>"text/openapi"</js>.
	 *
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> openapi() {
		marshall(OpenApi.DEFAULT);
		return this;
	}

	/**
	 * Associates the specified {@link Marshall} with this client.
	 *
	 * <p>
	 * This is shorthand for calling <c>serializer(x)</c> and <c>parser(x)</c> using the inner
	 * serializer and parser of the marshall object.
	 *
	 * @param value
	 * 	The marshall to use for serializing and parsing HTTP bodies.
	 * 	<br>Can be <jk>null</jk> (will remote the existing serializer/parser).
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> marshall(Marshall value) {
		if (value != null)
			serializer(value.getSerializer()).parser(value.getParser());
		else
			serializer(null).parser(null);
		return this;
	}

	/**
	 * Associates the specified {@link Serializer} with this client.
	 *
	 * @param value
	 * 	The serializer to use for serializing HTTP bodies.
	 * 	<br>Can be <jk>null</jk> (will remote the existing serializer).
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> serializer(Serializer value) {
		rcb.serializer(value);
		contentType(value == null ? null : value.getPrimaryMediaType().toString());
		return this;
	}

	/**
	 * Associates the specified {@link Parser} with this client.
	 *
	 * @param value
	 * 	The parser to use for parsing HTTP bodies.
	 * 	<br>Can be <jk>null</jk> (will remote the existing parser).
	 * @return This object (for method chaining).
	 */
	public MockRemoteResource<T> parser(Parser value) {
		rcb.parser(value);
		accept(value == null ? null : value.getPrimaryMediaType().toString());
		return this;
	}
}
