<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

using WhenItsDone.Data.Contracts;
using WhenItsDone.Data.UnitsOfWork.Factories;
using WhenItsDone.Models.Contracts;

namespace WhenItsDone.Services.Abstraction
{
    public abstract class FactoryGenericAsyncService<T>
            where T : class, IDbModel
    {
        private readonly IRepository<T> repository;
        private readonly IUnitOfWorkFactory unitOfWorkFactory;

        public FactoryGenericAsyncService(IRepository<T> repository, IUnitOfWorkFactory unitOfWorkFactory)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }

            if (unitOfWorkFactory == null)
            {
                throw new ArgumentNullException(nameof(unitOfWorkFactory));
            }

            this.repository = repository;
            this.unitOfWorkFactory = unitOfWorkFactory;
        }

        public virtual T GetById(int id)
        {
            return this.repository.GetById(id);
        }

        public virtual async Task<T> Add(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for add!");
            }

            this.repository.Add(item);
            this.SaveChangesToDb();

            return this.GetById(item.Id);
        }

        public virtual async Task<T> Update(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for update!");
            }

            this.repository.Update(item);
            this.SaveChangesToDb();

            return this.GetById(item.Id);
        }

        public virtual async Task<int> Hide(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for hide!");
            }

            item.IsDeleted = true;
            this.repository.Update(item);
            this.SaveChangesToDb();
        }

        public virtual async Task<int> Delete(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for delete!");
            }

            this.repository.Delete(item);
            this.SaveChangesToDb();
        }

        public virtual async Task<IEnumerable<T>> GetAll()
        {
            return await Task.Run(() => this.repository.GetAll());
        }

        public virtual async Task<IEnumerable<T>> GetAll(Expression<Func<T, bool>> filter)
        {
            return await Task.Run(() => this.repository.GetAll(filter));
        }

        public virtual async Task<IEnumerable<T>> GetAll<T1>(Expression<Func<T, bool>> filter,
                                                    Expression<Func<T, T1>> orderBy)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy));
        }

        public virtual async Task<IEnumerable<TResult>> GetAll<T1, TResult>(Expression<Func<T, bool>> filter,
                                            Expression<Func<T, T1>> orderBy,
                                            Expression<Func<T, TResult>> select)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, select));
        }

        public virtual async Task<IEnumerable<T>> GetAll(Expression<Func<T, bool>> filter,
                                        int page,
                                        int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, page, pageSize));
        }

        public virtual async Task<IEnumerable<T>> GetAll<T1>(Expression<Func<T, bool>> filter,
                                        Expression<Func<T, T1>> orderBy,
                                        int page,
                                        int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, page, pageSize));
        }

        public virtual async Task<IEnumerable<TResult>> GetAll<T1, TResult>(Expression<Func<T, bool>> filter,
                                            Expression<Func<T, T1>> orderBy,
                                            Expression<Func<T, TResult>> select,
                                            int page,
                                            int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, select, page, pageSize));
        }

        public virtual async Task<IEnumerable<T>> GetDeleted()
        {
            return await Task.Run(() => this.GetAll((x) => x.IsDeleted));
        }

        protected abstract bool IsValid(T item);

        private async void SaveChangesToDb()
        {
            using (var uow = this.unitOfWorkFactory.CreateUnitOfWork())
            {
                await uow.SaveChanges();
            }
        }<commit_msg>updated factory generic service<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

using WhenItsDone.Data.Contracts;
using WhenItsDone.Data.UnitsOfWork.Factories;
using WhenItsDone.Models.Contracts;

namespace WhenItsDone.Services.Abstraction
{
    public abstract class FactoryGenericAsyncService<T>
            where T : class, IDbModel
    {
        private readonly IRepository<T> repository;
        private readonly IUnitOfWorkFactory unitOfWorkFactory;

        public FactoryGenericAsyncService(IRepository<T> repository, IUnitOfWorkFactory unitOfWorkFactory)
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }

            if (unitOfWorkFactory == null)
            {
                throw new ArgumentNullException(nameof(unitOfWorkFactory));
            }

            this.repository = repository;
            this.unitOfWorkFactory = unitOfWorkFactory;
        }

        public virtual T GetById(int id)
        {
            return this.repository.GetById(id);
        }

        public virtual async Task<T> Add(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for add!");
            }

            this.repository.Add(item);
            using (var uow = this.unitOfWorkFactory.CreateUnitOfWork())
            {
                await uow.SaveChanges();
            }

            return this.GetById(item.Id);
        }

        public virtual async Task<T> Update(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for update!");
            }

            this.repository.Update(item);
            using (var uow = this.unitOfWorkFactory.CreateUnitOfWork())
            {
                await uow.SaveChanges();
            }

            return this.GetById(item.Id);
        }

        public virtual async Task<int> Hide(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for hide!");
            }

            item.IsDeleted = true;
            this.repository.Update(item);
            using (var uow = this.unitOfWorkFactory.CreateUnitOfWork())
            {
                return await uow.SaveChanges();
            }
        }

        public virtual async Task<int> Delete(T item)
        {
            if (item == null || !this.IsValid(item))
            {
                throw new ArgumentException("Invalid item for delete!");
            }

            this.repository.Delete(item);
            using (var uow = this.unitOfWorkFactory.CreateUnitOfWork())
            {
                return await uow.SaveChanges();
            }
        }

        public virtual async Task<IEnumerable<T>> GetAll()
        {
            return await Task.Run(() => this.repository.GetAll());
        }

        public virtual async Task<IEnumerable<T>> GetAll(Expression<Func<T, bool>> filter)
        {
            return await Task.Run(() => this.repository.GetAll(filter));
        }

        public virtual async Task<IEnumerable<T>> GetAll<T1>(Expression<Func<T, bool>> filter,
                                                    Expression<Func<T, T1>> orderBy)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy));
        }

        public virtual async Task<IEnumerable<TResult>> GetAll<T1, TResult>(Expression<Func<T, bool>> filter,
                                            Expression<Func<T, T1>> orderBy,
                                            Expression<Func<T, TResult>> select)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, select));
        }

        public virtual async Task<IEnumerable<T>> GetAll(Expression<Func<T, bool>> filter,
                                        int page,
                                        int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, page, pageSize));
        }

        public virtual async Task<IEnumerable<T>> GetAll<T1>(Expression<Func<T, bool>> filter,
                                        Expression<Func<T, T1>> orderBy,
                                        int page,
                                        int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, page, pageSize));
        }

        public virtual async Task<IEnumerable<TResult>> GetAll<T1, TResult>(Expression<Func<T, bool>> filter,
                                            Expression<Func<T, T1>> orderBy,
                                            Expression<Func<T, TResult>> select,
                                            int page,
                                            int pageSize)
        {
            return await Task.Run(() => this.repository.GetAll(filter, orderBy, select, page, pageSize));
        }

        public virtual async Task<IEnumerable<T>> GetDeleted()
        {
            return await Task.Run(() => this.GetAll((x) => x.IsDeleted));
        }

        protected abstract bool IsValid(T item);
{'fraction_non_alphanumeric': 0.09851033157135992, 'fraction_numerical': 0.001537722248918789, 'mean_word_length': 1.5411477411477412, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 123, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 46, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '832731', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2466, 'n_words': 579}