// Espacio de nombres que reune objetos DTO (data transfer object ) para comunicación con capa de presentación.
// Los DTO no incluyen lógica, solo datos (no son un remplazo de las Entidades - objetos del negocio.)
using System;

namespace EvaPosSrvDTO
{
    /// <summary>
    /// TipoMensaje encapsula identificadores permitidos de tipo de mensaje. 
    /// </summary> 
    public class TipoMensaje
    {
        /// <summary>
        /// Valor del tipo de mensaje. 
        /// </summary> 
        //REVISAR: Creado para xml, set era private
        public string Tipo { get;  set; }

        //REVISAR: Creado para xml constructor vacio
        public TipoMensaje()
        {
            
        }
        private TipoMensaje(string tipo)
        {
            Tipo = tipo;
        }
        /// <summary>
        /// Mensajes tipo EVENT. 
        /// </summary> 
        //REVISAR: Creado para xml, set era private
        public static TipoMensaje Event { get;  set; } = new TipoMensaje("EVENT");
        /// <summary>
        /// Mensajes tipo REQest. 
        /// </summary> 
        //REVISAR: Creado para xml, set era private
        public static TipoMensaje Req { get;  set; } = new TipoMensaje("REQ");
        /// <summary>
        /// Mensajes tipo RESPonse. 
        /// </summary> 
        //REVISAR: Creado para xml, set era private
        public static TipoMensaje Resp { get;  set; } = new TipoMensaje("RESP");
        /// <summary>
        /// Retorna un tipo de mensaje correspondiente al parámetro. 
        /// </summary> 
        public static TipoMensaje FijaTipoMensaje(string tipo)
        {
            var t = tipo switch
            {
                "REQ" => TipoMensaje.Req,
                "EVENT" => TipoMensaje.Event,
                "RESP" => TipoMensaje.Resp,
                _ => throw new Exception($"Tipo de mensaje no reconocido {tipo}")
            };
            return t;
        }
    }

    /// <summary>
    /// Clase base de DTO.
    /// </summary>
    public abstract class DTOBase
    {
        /// <summary>
        /// Id de la sesión.
        /// </summary>
        //REVISAR: Creado para xml, set era private
        public Int32 IdSesion { get;  set; }
        /// <summary>
        /// Tipo del mensaje.
        /// </summary>
        //REVISAR: Creado para xml, set era private
        public TipoMensaje TipoMensaje { get;  set; }
        
        /// <summary>
        /// Constructor base.
        /// </summary>
        public DTOBase(int idSesion, TipoMensaje tipo)
        {
            IdSesion = idSesion;
            TipoMensaje = tipo;
        }
        //REVISAR: Creado para xml, set era private, cosntructor vacio
        public DTOBase()
        {
        }
    }


    // TODO - ARREGLAR EL MECANISMO DE TERMINACION DEL SERVIDOR.
    /// <summary>
    /// DTO con mensaje de terminación de conexión, para pruebas.
    /// </summary>
    public class FinDePruebaDTO : DTOBase
    {
        /// <summary>
        /// Mensaje de terminación de conexión, para pruebas.
        /// </summary>
        public string MensajeFin { get; private set; } = "<|ACK|>";

        public FinDePruebaDTO() : base(1, TipoMensaje.Event)
        {}
    }

    // TODO - validar manejo de errores y su notificación a clientes que interactuan con el servidor.
    /// <summary>
    /// Retorna mensajes de error.
    /// </summary>
    public class ErrorDTO : DTOBase
    {
        /// <summary>
        /// Texto del mensaje de error.
        /// </summary>
        public string Texto { get; private set; }

        /// <summary>
        /// Constructor con texto del mensaje de error.
        /// </summary>
        public ErrorDTO(int sessionId, TipoMensaje messageType, string texto) : base(sessionId, messageType)
        {
            Texto = texto;
        }

        /// <summary>
        /// Representación del objeto en un string.
        /// </summary>
        public override string ToString()
        {
            return $"ErrorDTO - Texto: {Texto}";
        }
    }

    /// <summary>
    /// InitializeRequest DTO
    /// </summary>
    public class InitializeRequestDTO : DTOBase
    {
        /// <summary>
        /// Campo OperatorID
        /// </summary>
        public string OperatorID { get; set; }
        /// <summary>
        /// Campo TerminalNumber
        /// </summary>
        public int TerminalNumber { get; set; } 
        /// <summary>
        /// Campo Recovery
        /// </summary>
        public bool Recovery { get; set; }

        public InitializeRequestDTO(int sessionId, TipoMensaje messageType) : base(sessionId, messageType) {}
    }
}