// ------------------------------------------------------------------------------------
// <copyright file="UsuariosDAL.cs" company="Universidad Distrital">
// Copyright (c) Universidad Distrital. All rights reserved.
// </copyright>
// <author>Camilo Prieto</author>
// ------------------------------------------------------------------------------------
namespace Biblioteca.Datos.Clases.DAL.Repositorio
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Linq.Expressions;
	using System.Threading.Tasks;
	using Biblioteca.Datos.Contexto;
	using Biblioteca.Datos.Contexto.Repositorio;
	using Biblioteca.IC.Acciones.Repositorio;
	using Biblioteca.IC.DTO.Repositorio;
	using TransaccionalNet.EF.Clases;
	using UtilitariosNet.Clases.Comunes.Entidades;
	using UtilitariosNet.Clases.Mapeador.Extensiones;

	/// <summary>
	/// Clase con las acciones de repositorio para la entidad Usuarios
	/// </summary>
	public class UsuariosDAL : AccesoComunDAL<ContextoBiblioteca>, IUsuariosRepositorioAccion
	{
		/// <summary>
		/// Objeto para entidad respuesta
		/// </summary>
		Respuesta<IUsuariosDTO> respuesta;

		/// <summary>
		/// Objeto para repositorio Usuarios
		/// </summary>
		RepositorioGenerico<Usuarios> repositorio;

		/// <summary>
		/// Inicializa una nueva instancia de la clase UsuariosDAL
		/// </summary>
		public UsuariosDAL()
		{
			this.respuesta = new Respuesta<IUsuariosDTO>();
			this.repositorio = new RepositorioGenerico<Usuarios>(ContextoBD);
		}

		/// <summary>
		/// Metodo editar usuarios
		/// </summary>
		/// <param name="usuarios">Entidad a editar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
		public async Task<Respuesta<IUsuariosDTO>> EditarUsuariosAsync(IUsuariosDTO usuarios)
		{
			return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
			{
				Usuarios UsuariosEntidad = repositorio.BuscarPor(entidad => entidad
					.IdUsuario == usuarios.IdUsuario).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(usuarios, UsuariosEntidad);
				repositorio.Editar(UsuariosEntidad);
				repositorio.Guardar();
				return respuesta;
			});
		}

		/// <summary>
		/// Metodo editar  usuarios por filtro 
		/// </summary>
		/// <param name="usuarios">Entidad con los datos a editar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
		public async Task<Respuesta<IUsuariosDTO>> EditarUsuariosPorFiltroAsync(IUsuariosDTO usuarios, params string[] propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                Usuarios usuariosEntidad = repositorio.BuscarPor(entidad => entidad
                .IdUsuario == usuarios.IdUsuario).FirstOrDefault();
                Mapeador.MapearObjetosPorPropiedadPorFiltro(usuarios, usuariosEntidad, propiedades);
                repositorio.Editar(usuariosEntidad);
                      repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar usuarios por query 
		/// </summary>
		/// <param name="filtro">Filtro de las entidades </param>
		/// <param name="valor">Entidad a mofificar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
		public async Task<Respuesta<IUsuariosDTO>> EditarPorQueryUsuariosAsync(Expression<Func<IUsuariosDTO, bool>> filtro, IUsuariosDTO valor, List<string> propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
          Usuarios UsuariosEntidad = Mapeador.MapearEntidadDTO(valor, new Usuarios());
                Expression<Func<Usuarios, bool>> filtros = Mapeador.MapearExpresion<IUsuariosDTO, Usuarios>(filtro);
                await repositorio.EditarPorQueryAsync(filtros, UsuariosEntidad, propiedades);
                await repositorio.GuardarAsync();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar usuarios lista 
		/// </summary>
		/// <param name="lista"> Lista con entidades a modificar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
		public async Task<Respuesta<IUsuariosDTO>> EditarListaUsuariosAsync(List<IUsuariosDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                List<Usuarios> listaUsuarios = new List<Usuarios>();
                listaUsuarios = Mapeador.MapearALista<IUsuariosDTO, Usuarios>(lista);
               await repositorio.EditarListaAsync(listaUsuarios);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo eliminar usuarios
		/// </summary>
		/// <param name="usuarios">Entidad a eliminar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> EliminarUsuariosAsync(IUsuariosDTO usuarios)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
				Usuarios UsuariosEntidad = repositorio.BuscarPor(entidad => entidad
					.IdUsuario == usuarios.IdUsuario).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(usuarios, UsuariosEntidad);
				repositorio.Eliminar(UsuariosEntidad);
                repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo eliminar lista usuarios 
		/// </summary>
		/// <param name="lista">Lista de entidad a eliminar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> EliminarListaUsuariosAsync(List<IUsuariosDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                List<Usuarios> listaUsuarios = new List<Usuarios>();
                listaUsuarios = Mapeador.MapearALista<IUsuariosDTO, Usuarios>(lista);
               await repositorio.EliminarListaAsync(listaUsuarios);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo guardar usuarios
		/// </summary>
		/// <param name="usuarios">Entidad a guardar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> GuardarUsuariosAsync(IUsuariosDTO usuarios)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                Usuarios UsuariosEntidad = Mapeador.MapearEntidadDTO(usuarios, new Usuarios());
               await repositorio.AgregarAsync(UsuariosEntidad);
               await repositorio.GuardarAsync();
                respuesta.Entidades.Add(UsuariosEntidad);
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo Guardar lista usuarios
		/// </summary>
		/// <param name="listaUsuarios">Lista de entidades a guardar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> GuardarListaUsuariosAsync(List<IUsuariosDTO> listaUsuarios)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                List<Usuarios> listaUsuariosEntidad = Mapeador.MapearALista<IUsuariosDTO, Usuarios>(listaUsuarios);
               await repositorio.AgregarListaAsync(listaUsuariosEntidad);
                respuesta.Entidades.AddRange(listaUsuariosEntidad);
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo consultar lista usuarios
		/// </summary>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> ConsultarListaUsuariosAsync()
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarTodos().ToList<IUsuariosDTO>();
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo consultar lista usuarios por filtro 
		/// </summary>
		/// <param name="usuarios">Entidad con los datos a filtrar</param>
		/// <param name="filtro">Filtro de las entidades </param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> ConsultarListaUsuariosPorFiltroAsync(Expression<Func<IUsuariosDTO, bool>> filtro)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarPor(Mapeador.MapearExpresion<IUsuariosDTO, Usuarios>(filtro)).ToList<IUsuariosDTO>();
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo consultar por llave usuarios
		/// </summary>
		/// <param name="usuarios">Entidad a consultar</param>
		/// <returns>Respuesta tipo Usuarios </returns>
        public async Task<Respuesta<IUsuariosDTO>> ConsultarUsuariosLlaveAsync(IUsuariosDTO usuarios)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IUsuariosDTO>, UsuariosDAL>(async () =>
            {
                respuesta.Entidades = (from entidad in ContextoBD.Usuarios
                                       where entidad.IdUsuario == usuarios.IdUsuario
                                       select entidad).ToList<IUsuariosDTO>();

                return respuesta;

            });
        }
    }
}

