using System.Threading;
using System.Threading.Tasks;
using Dacryptero.DB;

namespace Dacryptero.Search.AST
{
    public class Word : AstBase
    {
        public string Text { get; }

        public Word(string text)
        {
            Text = text;
        }

        public override string ToString()
        {
            return $"{GetType().Name}: {Text}";
        }

        public override AstBase Clone()
        {
            return this;
        }

        public override SearchProgress Check(SearchContext context)
        {
            var (score, res) = SingleFieldSearcher.Search(
                context.Part.Type,
                context.Part.Name,
                context.Part.Value,
                Text
            );
            var col = res is null ? new Collections.TreeCollection<ResultFound>()
                : new Collections.TreeCollection<ResultFound>(res);
            return new SearchProgress(score, col);
        }

        public override async Task<SearchIndex> GetSearchIndexAsync(DBSingleController db,
            Data.IndexSource source, CancellationToken cancellationToken
        )
        {
            var index = SearchIndex.All;
            foreach (var token in Data.Index.Tokenify(Text))
            {
                var entry = await db.GetIndex(token, source, cancellationToken).ConfigureAwait(false);
                Serilog.Log.Verbose("Word Search: source={source} token='{token}' index={index}", source, token, entry);
                index.IntersectWith(entry);
            }
            return index;
        }
    }
}