// ------------------------------------------------------------------------------------
// <copyright file="PaisesDAL.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 Paises
	/// </summary>
	public class PaisesDAL : AccesoComunDAL<ContextoBiblioteca>, IPaisesRepositorioAccion
	{
		/// <summary>
		/// Objeto para entidad respuesta
		/// </summary>
		Respuesta<IPaisesDTO> respuesta;

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

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

		/// <summary>
		/// Metodo editar paises
		/// </summary>
		/// <param name="paises">Entidad a editar</param>
		/// <returns>Respuesta tipo Paises </returns>
		public async Task<Respuesta<IPaisesDTO>> EditarPaisesAsync(IPaisesDTO paises)
		{
			return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
			{
				Paises PaisesEntidad = repositorio.BuscarPor(entidad => entidad
					.IdPais == paises.IdPais).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(paises, PaisesEntidad);
				repositorio.Editar(PaisesEntidad);
				repositorio.Guardar();
				return respuesta;
			});
		}

		/// <summary>
		/// Metodo editar  paises por filtro 
		/// </summary>
		/// <param name="paises">Entidad con los datos a editar</param>
		/// <param name="propiedades">Propiedades a modificar</param>
		/// <returns>Respuesta tipo Paises </returns>
		public async Task<Respuesta<IPaisesDTO>> EditarPaisesPorFiltroAsync(IPaisesDTO paises, params string[] propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                Paises paisesEntidad = repositorio.BuscarPor(entidad => entidad
                .IdPais == paises.IdPais).FirstOrDefault();
                Mapeador.MapearObjetosPorPropiedadPorFiltro(paises, paisesEntidad, propiedades);
                repositorio.Editar(paisesEntidad);
                      repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar paises 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 Paises </returns>
		public async Task<Respuesta<IPaisesDTO>> EditarPorQueryPaisesAsync(Expression<Func<IPaisesDTO, bool>> filtro, IPaisesDTO valor, List<string> propiedades)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
          Paises PaisesEntidad = Mapeador.MapearEntidadDTO(valor, new Paises());
                Expression<Func<Paises, bool>> filtros = Mapeador.MapearExpresion<IPaisesDTO, Paises>(filtro);
                await repositorio.EditarPorQueryAsync(filtros, PaisesEntidad, propiedades);
                await repositorio.GuardarAsync();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo editar paises lista 
		/// </summary>
		/// <param name="lista"> Lista con entidades a modificar</param>
		/// <returns>Respuesta tipo Paises </returns>
		public async Task<Respuesta<IPaisesDTO>> EditarListaPaisesAsync(List<IPaisesDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                List<Paises> listaPaises = new List<Paises>();
                listaPaises = Mapeador.MapearALista<IPaisesDTO, Paises>(lista);
               await repositorio.EditarListaAsync(listaPaises);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo eliminar paises
		/// </summary>
		/// <param name="paises">Entidad a eliminar</param>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> EliminarPaisesAsync(IPaisesDTO paises)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
				Paises PaisesEntidad = repositorio.BuscarPor(entidad => entidad
					.IdPais == paises.IdPais).FirstOrDefault();
				Mapeador.MapearObjetosPorPropiedad(paises, PaisesEntidad);
				repositorio.Eliminar(PaisesEntidad);
                repositorio.Guardar();
                return respuesta;
            });
        }


		/// <summary>
		/// Metodo eliminar lista paises 
		/// </summary>
		/// <param name="lista">Lista de entidad a eliminar</param>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> EliminarListaPaisesAsync(List<IPaisesDTO> lista)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                List<Paises> listaPaises = new List<Paises>();
                listaPaises = Mapeador.MapearALista<IPaisesDTO, Paises>(lista);
               await repositorio.EliminarListaAsync(listaPaises);
               await repositorio.GuardarAsync();
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo guardar paises
		/// </summary>
		/// <param name="paises">Entidad a guardar</param>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> GuardarPaisesAsync(IPaisesDTO paises)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                Paises PaisesEntidad = Mapeador.MapearEntidadDTO(paises, new Paises());
               await repositorio.AgregarAsync(PaisesEntidad);
               await repositorio.GuardarAsync();
                respuesta.Entidades.Add(PaisesEntidad);
                return respuesta;

            });
        }

		/// <summary>
		/// Metodo Guardar lista paises
		/// </summary>
		/// <param name="listaPaises">Lista de entidades a guardar</param>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> GuardarListaPaisesAsync(List<IPaisesDTO> listaPaises)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                List<Paises> listaPaisesEntidad = Mapeador.MapearALista<IPaisesDTO, Paises>(listaPaises);
               await repositorio.AgregarListaAsync(listaPaisesEntidad);
                respuesta.Entidades.AddRange(listaPaisesEntidad);
                return respuesta;
            });
        }

		/// <summary>
		/// Metodo consultar lista paises
		/// </summary>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> ConsultarListaPaisesAsync()
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                respuesta.Entidades = repositorio.BuscarTodos().ToList<IPaisesDTO>();
                return respuesta;

            });
        }

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

            });
        }

		/// <summary>
		/// Metodo consultar por llave paises
		/// </summary>
		/// <param name="paises">Entidad a consultar</param>
		/// <returns>Respuesta tipo Paises </returns>
        public async Task<Respuesta<IPaisesDTO>> ConsultarPaisesLlaveAsync(IPaisesDTO paises)
        {
            return await this.EjecutarTransaccionAsync<Respuesta<IPaisesDTO>, PaisesDAL>(async () =>
            {
                respuesta.Entidades = (from entidad in ContextoBD.Paises
                                       where entidad.IdPais == paises.IdPais
                                       select entidad).ToList<IPaisesDTO>();

                return respuesta;

            });
        }
    }
}

