using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Dacryptero.DB;
using Dacryptero.Search.Sorting;

namespace Dacryptero.Search.AST
{
    public class AndGroup : AstCollectionBase
    {
        public bool CalcMaximum { get; }

        public AndGroup(bool calcMaximum)
        {
            CalcMaximum = calcMaximum;
        }

        protected override AstCollectionBase CloneCollection()
        {
            return new AndGroup(CalcMaximum);
        }

        public override SearchProgress Check(SearchContext context)
        {
            var result = new List<Collections.TreeCollection<ResultFound>>(Items.Count);
            var score = 0.0;
            foreach (var item in Items)
            {
                var prog = item.Check(context);
                if (!prog.IsSuccess)
                    return new SearchProgress();
                result.Add(prog.Previews);
                score = CalcMaximum ? Math.Max(score, prog.Score) : score + prog.Score;
            }
            return new SearchProgress(score, new Collections.TreeCollection<ResultFound>(result));
        }

        public override async Task<SearchIndex> GetSearchIndexAsync(DBSingleController db,
            Data.IndexSource source, CancellationToken cancellationToken
        )
        {
            var index = SearchIndex.All;
            foreach (var item in Items)
            {
                var entry = await item.GetSearchIndexAsync(db, source, cancellationToken)
                    .ConfigureAwait(false);
                index.IntersectWith(entry);
            }
            return index;
        }
    }
}