package com.ejie.ab79.rest.serviciosWeb;

import java.util.Locale;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ejie.ab79.comun.Constantes;
import com.ejie.ab79.comun.TrazabilidadUtils;
import com.ejie.ab79.exceptions.Ab79Exception;
import com.ejie.ab79.model.EnviosJson;
import com.ejie.ab79.model.Inspectores;
import com.ejie.ab79.model.REST.servicioWeb.DocumentacionActuacion;
import com.ejie.ab79.model.REST.servicioWeb.DocumentacionInformeTecnico;
import com.ejie.ab79.model.REST.servicioWeb.DocumentoWS;
import com.ejie.ab79.model.REST.servicioWeb.GenericResponse;
import com.ejie.ab79.model.REST.servicioWeb.InspeccionDato;
import com.ejie.ab79.model.REST.servicioWeb.InspeccionesDatosPadre;
import com.ejie.ab79.model.REST.servicioWeb.InspeccionesDocumentacionPadre;
import com.ejie.ab79.model.REST.servicioWeb.ListaInspeccionesDatosPadre;
import com.ejie.ab79.model.REST.servicioWeb.ListaInspeccionesDocumentacionPadre;
import com.ejie.ab79.model.REST.servicioWeb.Url;
import com.ejie.ab79.model.REST.servicioWeb.VerificarDocumento;
import com.ejie.ab79.model.actuaciones.ResultadosActuacion;
import com.ejie.ab79.model.actuaciones.TiposActuacion;
import com.ejie.ab79.model.expedientes.TiposDocumento;
import com.ejie.ab79.model.inspecciones.CampainasInspeccion;
import com.ejie.ab79.model.inspecciones.EstadosInspeccion;
import com.ejie.ab79.model.nora.T17Localidad;
import com.ejie.ab79.model.nora.T17Municipio;
import com.ejie.ab79.model.nora.T17Provincia;
import com.ejie.ab79.model.plantillas.ParametrosConfig;
import com.ejie.ab79.model.plantillas.TiposPlantilla;
import com.ejie.ab79.model.preguntasRespuestas.PreguntasProtocolo;
import com.ejie.ab79.model.preguntasRespuestas.TiposPreguntas;
import com.ejie.ab79.model.procedimientos.Procedimientos;
import com.ejie.ab79.model.protocolos.Protocolos;
import com.ejie.ab79.model.user.User;
import com.ejie.ab79.service.TrazabilidadService;
import com.ejie.ab79.service.REST.serviciosWeb.ServiciosWebRESTService;
import com.ejie.ab79.service.plantillas.ParametrosConfigService;
import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * 
 *  
 *
 */
@Controller()
@RequestMapping(value = "/webservice", produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
public class WebServiceController {

	private static final Logger logger = LoggerFactory.getLogger(WebServiceController.class);

	@Autowired()
	private ServiciosWebRESTService serviciosWebRESTService;

	@Autowired()
	private TrazabilidadService trazabilidadService;

	@Autowired()
	private ParametrosConfigService parametrosConfigService;

	@Resource()
	ReloadableResourceBundleMessageSource appMessageSource;

	@ModelAttribute("resetTrazabilidad")
	public void resetTrazabilidad() {
		this.trazabilidadService.resetActivo();
	}

	/**
	 * Capturamos los JSON que no se pueden capturar en los métodos.
	 * 
	 * @param request
	 *            HttpServletRequest
	 * @param response
	 *            HttpServletResponse
	 * @param e
	 *            HttpMessageNotReadableException
	 * @return GenericResponse
	 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public @ResponseBody() GenericResponse handle400(HttpServletRequest request, HttpServletResponse response,
			HttpMessageNotReadableException e,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication) {
		response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
		String error = "error.400";

		// Guardar traza
		StringBuffer path = request.getRequestURL();
		String pathStr = path.toString();

		String metodo = pathStr.substring(pathStr.lastIndexOf('/') + 1, pathStr.length());

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), null, metodo, null,
				e.getLocalizedMessage());

		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception ex) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(ex);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_ERROR, error,
				this.appMessageSource.getMessage(error, null, new Locale("es")),
				this.appMessageSource.getMessage(error, null, new Locale("eu")));
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterEstadosInspeccion
	 *            EstadosInspeccion Objeto que contiene los parametros de
	 *            filtrado utilizados en la busqueda.
	 * @return JSON con la lista de Estados de la inspeccion
	 * @throws JsonProcessingException
	 */

	@RequestMapping(value = "/obtenerEstadosInspeccion", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerEstadosInspeccion(HttpServletResponse response)
			throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerEstadosInspeccion] : ***************************************");
		WebServiceController.logger.info("[obtenerEstadosInspeccion] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerEstadosInspeccion] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerEstadosInspeccion(response, new EstadosInspeccion());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterResultadosActuacion
	 *            ResultadosActuacion Objeto que contiene los parametros de
	 *            filtrado utilizados en la busqueda.
	 * @return JSON con la lista de Resultados de la actuaciÃ³n
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerResultadosActuacion", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerResultadosActuacion(HttpServletResponse response)
			throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerResultadosActuacion] : ***************************************");
		WebServiceController.logger.info("[obtenerResultadosActuacion] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerResultadosActuacion] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerResultadosActuacion(response, new ResultadosActuacion());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterTiposDocumento
	 *            TiposDocumento Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Tipos de documento
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerTiposDocumento", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerTiposDocumento(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerTiposDocumento] : ***************************************");
		WebServiceController.logger.info("[obtenerTiposDocumento] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerTiposDocumento] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerTiposDocumento(response, new TiposDocumento());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterTiposPlantilla
	 *            TiposPlantilla Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Tipos de plantilla
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerTiposPlantilla", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerTiposPlantilla(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerTiposPlantilla] : ***************************************");
		WebServiceController.logger.info("[obtenerTiposPlantilla] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerTiposPlantilla] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerTiposPlantilla(response, new TiposPlantilla());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterInspectores
	 *            Inspectores Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Inspectores
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerInspectores", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerInspectores(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerInspectores] : ***************************************");
		WebServiceController.logger.info("[obtenerInspectores] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerInspectores] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerInspectores(response, new Inspectores());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterProtocolos
	 *            Protocolos Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Protocolos
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerProtocolos", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerProtocolos(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerProtocolos] : ***************************************");
		WebServiceController.logger.info("[obtenerProtocolos] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerProtocolos] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerProtocolos(response, new Protocolos());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterPreguntasProtocolo
	 *            PreguntasProtocolo Objeto que contiene los parametros de
	 *            filtrado utilizados en la busqueda.
	 * @return JSON con la lista de PreguntasProtocolo
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerPreguntasProtocolos", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerPreguntasProtocolos(HttpServletResponse response)
			throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerPreguntasProtocolos] : ***************************************");
		WebServiceController.logger.info("[obtenerPreguntasProtocolos] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerPreguntasProtocolos] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerPreguntasProtocolos(response, new PreguntasProtocolo());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterCampainasInspeccion
	 *            CampainasInspeccion Objeto que contiene los parametros de
	 *            filtrado utilizados en la busqueda.
	 * @return JSON con la lista de CampainasInspeccion
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerCampainas", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerCampainas(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerCampainas] : ***************************************");
		WebServiceController.logger.info("[obtenerCampainas] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerCampainas] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerCampainas(response, new CampainasInspeccion());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @return JSON con la lista de ActividadesCenso
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerDatosActCenso", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerDatosActCenso(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerDatosActCenso] : ***************************************");
		WebServiceController.logger.info("[obtenerDatosActCenso] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerDatosActCenso] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerDatosActCenso(response);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterProvincia
	 *            Provincia Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Provincias
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerProvincias", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerProvincias(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerProvincias] : ***************************************");
		WebServiceController.logger.info("[obtenerProvincias] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerProvincias] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerProvincias(response, new T17Provincia());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterMunicipios
	 *            T17Municipio Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Municipios
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerMunicipios", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerMunicipios(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerProvincias] : ***************************************");
		WebServiceController.logger.info("[obtenerProvincias] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerProvincias] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerMunicipios(response, new T17Municipio());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterLocalidades
	 *            T17Localidad Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Localidades
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerLocalidades", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerLocalidades(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerLocalidades] : ***************************************");
		WebServiceController.logger.info("[obtenerLocalidades] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerLocalidades] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerLocalidades(response, new T17Localidad());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterProcedimientos
	 *            Procedimientos Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Procedimientos que permiten crear
	 *         expedientes de inspecciÃ³n
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerProcedimientosInspeccion", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerProcedimientosInspeccion(HttpServletResponse response)
			throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerProcedimientosInspeccion] : ***************************************");
		WebServiceController.logger.info("[obtenerProcedimientosInspeccion] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerProcedimientosInspeccion] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerProcedimientosInspeccion(response, new Procedimientos());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterTiposPreguntas
	 *            TiposPreguntas Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Tipos de pregunta
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerTiposPregunta", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerTiposPregunta(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerTiposPregunta] : ***************************************");
		WebServiceController.logger.info("[obtenerTiposPregunta] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerTiposPregunta] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerTiposPregunta(response, new TiposPreguntas());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param filterTiposActuacion
	 *            TiposActuacion Objeto que contiene los parametros de filtrado
	 *            utilizados en la busqueda.
	 * @return JSON con la lista de Tipos de actuaciÃ³n
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerTiposActuacion", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerTiposActuacion(HttpServletResponse response) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerTiposActuacion] : ***************************************");
		WebServiceController.logger.info("[obtenerTiposActuacion] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerTiposActuacion] : ***************************************");

		try {
			return this.serviciosWebRESTService.obtenerTiposActuacion(response, new TiposActuacion());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return JSON con la lista de Inspecciones
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerInspecciones", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerInspecciones(HttpServletResponse response,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerInspecciones] : ***************************************");
		WebServiceController.logger.info("[obtenerInspecciones] : Sin parametros de entrada");
		WebServiceController.logger.info("[obtenerInspecciones] : ***************************************");

		Object respuesta = null;

		try {
			respuesta = this.serviciosWebRESTService.obtenerInspecciones(response);
			((ListaInspeccionesDatosPadre) respuesta).setTrazabilidad(this.estadoTrazabilidad());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			respuesta = new GenericResponse(e);
		}

		// Almacenamiento de trazas en ENVIOS_JSON.
		try {
			User user = (User) authentication.getCredentials();
			EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION,
					Constantes.CODIGO_APLICACION_MOVIL, user.getId(), user.getUserName(), null, "obtenerInspecciones",
					respuesta, null);
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
			((ListaInspeccionesDatosPadre) respuesta).setIdentificadorJson(envioJson.getIdEnvioJson());
		} catch (Exception e) {
		}

		return respuesta;
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return JSON con la lista de Documentación de las Inspecciones
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerDocumentacionInspecciones", method = RequestMethod.GET)
	public @ResponseBody() Object obtenerDocumentacionInspecciones(HttpServletResponse response,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException {
		WebServiceController.logger
				.info("[obtenerDocumentacionInspecciones] : ***************************************");
		WebServiceController.logger.info("[obtenerDocumentacionInspecciones] : Sin parametros de entrada");
		WebServiceController.logger
				.info("[obtenerDocumentacionInspecciones] : ***************************************");

		Object respuesta = null;

		try {
			respuesta = this.serviciosWebRESTService.obtenerDocumentacionInspecciones(response);
			((ListaInspeccionesDocumentacionPadre) respuesta).setTrazabilidad(this.estadoTrazabilidad());
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			respuesta = new GenericResponse(e);
		}

		// Almacenamiento de trazas en ENVIOS_JSON.
		try {
			User user = (User) authentication.getCredentials();
			EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION,
					Constantes.CODIGO_APLICACION_MOVIL, user.getId(), user.getUserName(), null,
					"obtenerDocumentacionInspecciones", respuesta, null);
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
			((ListaInspeccionesDocumentacionPadre) respuesta).setIdentificadorJson(envioJson.getIdEnvioJson());
		} catch (Exception e) {
		}

		return respuesta;
	}

	/**
	 * Devuelve una lista de beans correspondientes a los valores de filtrados
	 * indicados en el objeto pasado como parametro.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @param oid
	 *            String
	 * @param origen
	 *            Integer (1: PID, 2: Dokusi)
	 * @return JSON con la url de PIF
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "/obtenerDocumento", method = RequestMethod.POST)
	public @ResponseBody() Object obtenerDocumento(HttpServletResponse response,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication,
			@RequestBody() DocumentoWS documento) throws JsonProcessingException {
		WebServiceController.logger.info("[obtenerDocumento] : ***************************************");
		WebServiceController.logger.info("[obtenerDocumento] : oid --> " + documento.getOid());
		WebServiceController.logger.info("[obtenerDocumento] : origen --> " + documento.getOrigen());
		WebServiceController.logger.info("[obtenerDocumento] : ***************************************");
		Object respuesta = null;

		try {
			Url url = this.serviciosWebRESTService.obtenerDocumento(response, documento.getOid(),
					documento.getOrigen());
			url.setTrazabilidad(this.estadoTrazabilidad());
			respuesta = url;
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			respuesta = new GenericResponse(e);
		}

		// Almacenamiento de trazas en ENVIOS_JSON.
		try {
			User user = (User) authentication.getCredentials();
			EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION,
					Constantes.CODIGO_APLICACION_MOVIL, user.getId(), user.getUserName(), null, "obtenerDocumento",
					respuesta, null);
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
			((Url) respuesta).setIdentificadorJson(envioJson.getIdEnvioJson());
		} catch (Exception e) {
		}

		return respuesta;
	}

	/**
	 * Guarda una inspeccion (nueva o existente) junto con sus actuaciones.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param inspeccionDato
	 *            InspeccionDato
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/guardarInspeccion", method = RequestMethod.POST)
	public @ResponseBody() GenericResponse guardarInspeccion(HttpServletResponse response,
			@RequestBody() InspeccionDato inspeccionDato,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger.info("[guardarInspeccion] : ***************************************");
		WebServiceController.logger.info("[guardarInspeccion] : inspeccionDato --> " + inspeccionDato.toString());
		WebServiceController.logger.info("[guardarInspeccion] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), null, "guardarInspeccion",
				inspeccionDato, null);

		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			if (inspeccionDato.getDatosGenerales() != null
					&& inspeccionDato.getDatosGenerales().getDatosBasicos() != null) {
				this.serviciosWebRESTService.guardarInspeccion(inspeccionDato, envioJson);

				envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_CORRECTO);
				envioJson = this.trazabilidadService.updateEnviosJson(envioJson);

			} else {
				WebServiceController.logger.error("Es necesario que por lo menos disponga de Datos Basicos.");

				envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_ERROR);
				envioJson = this.trazabilidadService.updateEnviosJson(envioJson);

				throw new Ab79Exception("error.servicoREST.datosBasicos",
						"Es necesario que por lo menos disponga de Datos Basicos.",
						"Gutxienez oinarrizko datuak eduki behar ditu.");
			}
		} catch (Exception e) {
			envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_ERROR);
			envioJson = this.trazabilidadService.updateEnviosJson(envioJson);

			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Guarda un documento de un informe tecnico.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param documentacionInformeTecnico
	 *            DocumentacionInformeTecnico
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/guardarDocumentacionInformeTecnico", method = RequestMethod.POST)
	public @ResponseBody() GenericResponse guardarDocumentacionInformeTecnico(HttpServletResponse response,
			@RequestBody() DocumentacionInformeTecnico documentacionInformeTecnico,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger
				.info("[guardarDocumentacionInformeTecnico] : ***************************************");
		WebServiceController.logger.info("[guardarDocumentacionInformeTecnico] : documentacionInformeTecnico --> "
				+ documentacionInformeTecnico.toString());
		WebServiceController.logger
				.info("[guardarDocumentacionInformeTecnico] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), null,
				"guardarDocumentacionInformeTecnico", documentacionInformeTecnico, null);
		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			if (documentacionInformeTecnico.getIdDocumentoMovil() != null
					&& (documentacionInformeTecnico.getIdPregunta() != null
							|| documentacionInformeTecnico.getIdPreguntaMovil() != null)
					&& documentacionInformeTecnico.getOrigen() != null
					&& documentacionInformeTecnico.getTipoFichero() != null
					&& documentacionInformeTecnico.getNombreFichero() != null
					&& documentacionInformeTecnico.getContenidoFichero() != null) {
				this.serviciosWebRESTService.guardarDocumentacionInformeTecnico(documentacionInformeTecnico, envioJson);

				envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_CORRECTO);
				envioJson = this.trazabilidadService.updateEnviosJson(envioJson);
			} else {
				WebServiceController.logger.error("Es necesario que disponga de todos los datos obligatorios.");

				throw new Ab79Exception("error.servicoREST.datosBasicos",
						"Es necesario que disponga de todos los datos obligatorios.",
						"Nahitaezko datu guztiak eduki behar dituzu.");
			}
		} catch (Exception e) {
			envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_ERROR);
			envioJson = this.trazabilidadService.updateEnviosJson(envioJson);

			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Guarda un documento de una actuacion.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param documentacionActuacion
	 *            DocumentacionActuacion
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/guardarDocumentacionActuacion", method = RequestMethod.POST, produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
	public @ResponseBody() GenericResponse guardarDocumentacionActuacion(HttpServletResponse response,
			@RequestBody() DocumentacionActuacion documentacionActuacion,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger.info("[guardarDocumentacionActuacion] : ***************************************");
		WebServiceController.logger.info("[guardarDocumentacionActuacion] : guardarDocumentacionActuacion --> "
				+ documentacionActuacion.toString());
		WebServiceController.logger.info("[guardarDocumentacionActuacion] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), null, "guardarDocumentacionActuacion",
				documentacionActuacion, null);
		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			if (documentacionActuacion.getIdActuacionMovil() != null
					&& documentacionActuacion.getIdDocumentoMovil() != null
					&& documentacionActuacion.getIdPlantilla() != null
					&& documentacionActuacion.getNombreFichero() != null
					&& documentacionActuacion.getContenidoFichero() != null) {
				this.serviciosWebRESTService.guardarDocumentacionActuacion(documentacionActuacion, envioJson);

				envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_CORRECTO);
				envioJson = this.trazabilidadService.updateEnviosJson(envioJson);
			} else {
				WebServiceController.logger.error("Es necesario que disponga de todos los datos obligatorios.");

				throw new Ab79Exception("error.servicoREST.datosBasicos",
						"Es necesario que disponga de todos los datos obligatorios.",
						"Nahitaezko datu guztiak eduki behar dituzu.");
			}
		} catch (Exception e) {
			envioJson.setEstado(Constantes.ENVIO_JSON_ESTADO_ERROR);
			envioJson = this.trazabilidadService.updateEnviosJson(envioJson);

			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Verifica un listado de inspecciones.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param inspeccionesDatosPadre
	 *            InspeccionesDatosPadre
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/verificarInspecciones", method = RequestMethod.POST, produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
	public @ResponseBody() GenericResponse verificarInspecciones(HttpServletResponse response,
			@RequestBody() InspeccionesDatosPadre inspeccionesDatosPadre,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger.info("[verificarInspecciones] : ***************************************");
		WebServiceController.logger
				.info("[verificarInspecciones] : inspeccionesDatosPadre --> " + inspeccionesDatosPadre.toString());
		WebServiceController.logger.info("[verificarInspecciones] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), 1, "verificarInspecciones",
				inspeccionesDatosPadre, null);
		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			this.serviciosWebRESTService.guardarVerificarInspecciones(inspeccionesDatosPadre);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Verifica un listado de inspecciones.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param inspeccionesDocumentacionPadre
	 *            InspeccionesDocumentacionPadre
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/verificarDocumentacionInspecciones", method = RequestMethod.POST, produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
	public @ResponseBody() GenericResponse verificarDocumentacionInspecciones(HttpServletResponse response,
			@RequestBody() InspeccionesDocumentacionPadre inspeccionesDocumentacionPadre,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger
				.info("[verificarDocumentacionInspecciones] : ***************************************");
		WebServiceController.logger.info("[verificarDocumentacionInspecciones] : inspeccionesDocumentacionPadre --> "
				+ inspeccionesDocumentacionPadre.toString());
		WebServiceController.logger
				.info("[verificarDocumentacionInspecciones] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), 1, "verificarDocumentacionInspecciones",
				inspeccionesDocumentacionPadre, null);
		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			this.serviciosWebRESTService.guardarVerificarDocumentacionInspecciones(inspeccionesDocumentacionPadre);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Verifica un listado de inspecciones.
	 * 
	 * @param response
	 *            HttpResponse
	 * @param verificarDocumento
	 *            VerificarDocumento
	 * @param authentication
	 *            UsernamePasswordAuthenticationToken
	 * @return Resultado de la operación y posibles errores.
	 * @throws JsonProcessingException
	 * @throws Ab79Exception
	 */
	@RequestMapping(value = "/verificarDocumento", method = RequestMethod.POST, produces = Constantes.APPLICATION_JSON_UTF8_VALUE)
	public @ResponseBody() GenericResponse verificarDocumento(HttpServletResponse response,
			@RequestBody() VerificarDocumento verificarDocumento,
			@AuthenticationPrincipal UsernamePasswordAuthenticationToken authentication)
			throws JsonProcessingException, Ab79Exception {
		WebServiceController.logger.info("[verificarDocumento] : ***************************************");
		WebServiceController.logger
				.info("[verificarDocumento] : VerificarDocumento --> " + verificarDocumento.toString());
		WebServiceController.logger.info("[verificarDocumento] : ***************************************");

		User user = (User) authentication.getCredentials();
		EnviosJson envioJson = TrazabilidadUtils.guardadoEnviosJson(Constantes.CODIGO_APLICACION_MOVIL,
				Constantes.CODIGO_APLICACION, user.getId(), user.getUserName(), 1, "verificarDocumento",
				verificarDocumento, null);
		try {
			envioJson = this.trazabilidadService.addEnviosJson(envioJson);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		try {
			this.serviciosWebRESTService.guardarVerificarDocumento(verificarDocumento);
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return new GenericResponse(e);
		}

		return new GenericResponse(Constantes.ENVIO_JSON_ESTADO_CORRECTO, null, null, null);
	}

	/**
	 * Extrae de la base de datos la información necesaria para decir si la
	 * trazabilidad JSON está activa o no.
	 * 
	 * @return Integer
	 */
	private Integer estadoTrazabilidad() {
		ParametrosConfig parametrosConfig = new ParametrosConfig();
		parametrosConfig.setDescripcion(Constantes.TRAZABILIDAD_WEBSERVICE);
		parametrosConfig = this.parametrosConfigService.find(parametrosConfig);

		return parametrosConfig.getValor();
	}

}
