using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using System.Linq.Expressions;

namespace Tanshu.Accounts.Repository
{
    public class UnitOfWork<T> : IUnitOfWork where T : class
    {
        protected readonly ISession _session;
        private ITransaction _transaction;

        public UnitOfWork()
        {
            _session = SessionManager.Session;
            _transaction = _session.BeginTransaction();
        }
        public void Insert(T item)
        {
            _session.Save(item);
        }

        public void Update(T item)
        {
            _session.Update(item);
        }

        public void Delete(T item)
        {
            _session.Delete(item);
        }

        public void Delete(Expression<Func<T, bool>> query)
        {
            Delete(Get(query));
        }

        public T Get(Expression<Func<T, bool>> query)
        {
            return _session.QueryOver<T>()
                .Where(query)
                .SingleOrDefault();
        }

        public IList<T> List()
        {
            return _session.CreateCriteria<T>()
                .List<T>();
        }

        public IList<T> List(Expression<Func<T, bool>> query)
        {
            return _session.QueryOver<T>()
                .Where(query)
                .List();
        }

        public void Dispose()
        {
            if (_transaction != null)
                _transaction.Rollback();
        }

        public void SaveChanges()
        {
            if (_transaction == null)
                throw new InvalidOperationException("UnitOfWork have already been saved.");

            _transaction.Commit();
            _transaction = null;
        }
    }
}