using inutralia.Abstractions;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net;

namespace inutralia.API
{
    /// <summary>
    /// Interfaz genérico de comunicación con un Web Service
    /// </summary>
    public interface IWebService : IDataPersistenceService
    {
		/// <summary>
		/// Borra la información relativa a las credenciales
		/// </summary>
		void Reset();

		/// <summary>
        /// Establece las credenciales de acceso a la API
        /// </summary>
        /// <param name="username">Nombre del usuario accediendo a la API</param>
        /// <param name="password">Contraseña del usuario</param>
        void CredentialsSet (string username, string password);

		/// <summary>
		/// Registra un usuario en el servidor
		/// </summary>
		/// <param name="userName">Nombre del usuario solicitando registro</param>
		/// <param name="passWord">Contraseña del usuario solicitando registro</param>
		/// <param name="companyCode">Código de la compañía que solicita el registro</param>
		Task<HttpStatusCode?> RegisterUser(string userName, string passWord, string companyCode);

        /// <summary>
        /// Cambia la contraseña del usuario actual
        /// </summary>
        /// <param name="currPass">Contraseña actual (para verificación)</param>
        /// <param name="newPass">Nueva contraseña</param>
        Task<bool> PasswordChange(string currPass, string newPass);

		/// <summary>
		/// Obtiene de forma asíncrona una lista de elementos de cierto tipo
		/// </summary>
		/// <typeparam name="T">Tipo de datos de cada elemento</typeparam>
		/// <param name="path">Path de acceso al recurso de la API</param>
		/// <returns>Lista de elementos obtenidos</returns>
		Task<List<T>> RefreshListAsync<T>(string path);

		/// <summary>
		/// Petición directa al WebService
		/// </summary>
		/// <param name="method">Método HTTP de la petición</param>
		/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
		/// <param name="data">Objeto a serializar en la petición</param>
		/// <returns>Respuesta del servidor</returns>
		Task<HttpResponseMessage> RawMessage(HttpMethod method, string resourcePath, object data = null);

		/// <summary>
		/// Petición directa al WebService (GET)
		/// </summary>
		/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
		/// <param name="data">Objeto a serializar en la petición</param>
		/// <returns>Respuesta del servidor</returns>
		Task<HttpResponseMessage> RawMessage(string resourcePath, object data = null);

		/// <summary>
		/// Procesa la respuesta de una petición directa
		/// </summary>
		/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
		/// <param name="response">Respuesta devuelta por RawMessage</param>
		/// <param name="data">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
		/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
		Task<T> ResponseProcess<T>(HttpResponseMessage response, T data = null) where T : class;

		/// <summary>
		/// Realiza un petición directa y procesa su respuesta
		/// </summary>
		/// <typeparam name="T">Tipo de datos en el que convertir los datos de respuesta</typeparam>
		/// <param name="method">Método HTTP de la petición</param>
		/// <param name="resourcePath">Path del recurso REST al cual acceder</param>
		/// <param name="input">Objeto a serializar en la petición</param>
		/// <param name="output">Objeto a poblar con los datos de respuesta. Se creará un nuevo objeto si este parámetro es null</param>
		/// <returns>El objeto poblado / creado. Si el status de la petición no es 2XX se devuelve null</returns>
		Task<T> RawMessage<T>(HttpMethod method, string resourcePath, object input = null, T output = null) where T : class;

    }
}
