package com.jasamedika.medifirst2000.util.rest;

import com.google.gson.Gson;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

/**
 * Rest Util Class
 * 
 * @author Roberto
 */
public class RestUtil {

	private static final String CONTENT_TYPE = "Content-Type";

	/**
	 * get JSON response from Object
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<T> getJsonResponse(T src) {
		HttpHeaders headers = new HttpHeaders();
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(src, headers, OK);
	}

	/**
	 * get JSON response from Object with HTTP status
	 *
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<T> getJsonResponse(T src, HttpStatus status) {
		HttpHeaders headers = new HttpHeaders();
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		Map<String, Object> map = new HashMap<>();
		map.put("data", src);
		return new ResponseEntity(map, headers, status);
	}

	public static <T> ResponseEntity<T> getJsonResponse(T src, HttpStatus status,
			Map<String, String> mapHeaderMessage) {
		HttpHeaders headers = new HttpHeaders();
		if (null != mapHeaderMessage)
			for (String key : mapHeaderMessage.keySet())
				headers.add(key, mapHeaderMessage.get(key));
		Map<String, Object> map = new HashMap<>();
		map.put("messages", mapHeaderMessage);
		map.put("data", src);
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity(map, headers, status);
	}

	/**
	 * get JSON response from HTTP status only
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<T> getJsonHttpStatus(HttpStatus status) {
		return new ResponseEntity<>(status);
	}

	public static <T> ResponseEntity<T> getJsonHttpStatus(HttpStatus status, Map<String, String> mapHeaderMessage) {
		HttpHeaders headers = new HttpHeaders();
		if (null != mapHeaderMessage)
			for (String key : mapHeaderMessage.keySet())
				headers.add(key, mapHeaderMessage.get(key));
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(headers, status);
	}

	/**
	 * get JSON response from Set Object
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<Set<T>> defaultJsonResponse(Set<T> src) {
		HttpHeaders headers = new HttpHeaders();
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(src, headers, OK);
	}

	/**
	 * get JSON response from Set Object with custom header
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<Set<T>> defaultJsonResponse(Set<T> src, Map<String, String> mapHeaderMessage) {
		HttpHeaders headers = new HttpHeaders();
		if (null != mapHeaderMessage)
			for (String key : mapHeaderMessage.keySet())
				headers.add(key, mapHeaderMessage.get(key));
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(src, headers, OK);
	}

	/**
	 * get JSON response from List Object with custom header
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<List<T>> defaultJsonResponse(List<T> src, Map<String, String> mapHeaderMessage) {
		HttpHeaders headers = new HttpHeaders();
		if (null != mapHeaderMessage)
			for (String key : mapHeaderMessage.keySet())
				headers.add(key, mapHeaderMessage.get(key));
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(src, headers, OK);
	}

	/**
	 * get JSON response from List Object
	 * 
	 * @param <T>
	 *            source class
	 * @return @ResponseEntity
	 */
	public static <T> ResponseEntity<List<T>> defaultJsonResponse(List<T> src) {
		HttpHeaders headers = new HttpHeaders();
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(src, headers, OK);
	}

	/**
	 * get default JSON response from Object
	 * 
	 * @return @ResponseEntity
	 */
	public static ResponseEntity<String> defaultJsonResponse(Object src) {
		Gson gson = new Gson();
		HttpHeaders headers = new HttpHeaders();
		headers.set(CONTENT_TYPE, APPLICATION_JSON_VALUE);
		return new ResponseEntity<>(gson.toJson(src), headers, OK);
	}

	/**
	 * convert JSON to Object
	 *
	 * @param strJson
	 *            string source JSON
	 * @param type
	 *            class type result
	 */
	public static <T> T jsonToObject(String strJson, Class<T> type) {
		Gson gson = new Gson();
		return gson.fromJson(strJson, type);
	}

	/**
	 * convert object to json
	 *
	 */
	public static String toJson(Object object) {
		Gson gson = new Gson();
		return gson.toJson(object);
	}

}
