using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Benchmark.Models;
using RoaringDB;
using RoaringDB.Linq;
using RoaringDB.Providers;

namespace Benchmark.DataSources
{
    public class RoaringDBDictionarySource : IDataSource<Post>
    {
        private readonly RoaringDictionary<Post> _collection;

        public RoaringDBDictionarySource(IBitmapProvider provider)
        {
            _collection = new RoaringDictionary<Post>(provider);
        }

        public void AddMany(Post[] msgs)
        {
            _collection.AddMany(msgs);
            _collection.Optimize();
        }

        public bool Any()
            => _collection.CreateQuery().Any();
        public bool ContainsKey(uint key)
            => _collection.CreateQuery().ContainsKey(key);
        public int Count()
            => (int)_collection.CreateQuery().Count();
        public int Count(Func<Post, bool> func, Expression<Func<Post, bool>> expr)
            => (int)_collection.CreateQuery().Count(expr);
            
        public Post First()
            => _collection.CreateQuery().First();
        public Post Last()
            => _collection.CreateQuery().Last();
        public Post ElementAt(int index)
            => _collection.CreateQuery().ElementAt((uint)index);
        public Post GetItem(uint key)
            => _collection.CreateQuery().SingleOrDefault(x => x.Id == key);

        public uint Min(Func<Post, uint> func, Expression<Func<Post, uint>> expr)
            => (uint)_collection.CreateQuery().Min(expr);
        public uint Max(Func<Post, uint> func, Expression<Func<Post, uint>> expr)
            => (uint)_collection.CreateQuery().Max(expr);
        public double Average(Func<Post, long> func, Expression<Func<Post, long>> expr)
            => throw new NotSupportedException();
        public long Sum(Func<Post, long> func, Expression<Func<Post, long>> expr)
            => (long)_collection.CreateQuery().Sum(expr);
            
        public Post[] TakeTop<T>(Func<Post, T> func, Expression<Func<Post, T>> expr, int count)
            => _collection.CreateQuery().TakeTop(expr, (ulong)count).ToArray();
    }
}