﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WorldBankBBS.Logic;

namespace WorldBankBBS.SearchEngine
{
    public class SearchEngine
    {
        private readonly Session _session = null;

        public SearchEngine(Session session)
        {
            _session = session;
            Providers = new List<ISearchProviderBase>();
            foreach (var item in ConfigurationManager.AppSettings.AllKeys.Where(k => k.StartsWith("SearchKey-")))
            {
                var value = ConfigurationManager.AppSettings[item];
                var type = value.Split(':').Last();
                var assembly = value.Substring(0, value.LastIndexOf(":")) + ".dll";
                var provider = Activator.CreateInstanceFrom(assembly, type);
                if (provider.Unwrap() as ISearchProviderBase != null)
                {
                    Providers.Add(provider.Unwrap() as ISearchProviderBase);
                }
            }
        }

        public IList<ISearchProviderBase> Providers
        {
            get;
            private set;
        }

        public ISearchProviderBase GetProvider(string key)
        {
            return Providers.FirstOrDefault(p => p.Key.ToLower() == key.ToLower());
        }

        public IList<ISearchResult<T>> PerformSearch<T>(IList<string> terms, ISearchProvider<T> provider)
        {
            var results = new List<ISearchResult<T>>();

            provider.Results.Clear();

            if (provider.Find(terms))
            {
                results.AddRange(provider.Results);
            }

            return results;
        }

        public IList<ISearchResultBase> PerformSearch(IList<string> terms, IList<ISearchProviderBase> providers)
        {
            var result = new List<ISearchResultBase>();

            foreach (var provider in providers)
            {
                if (provider.Find(terms))
                {
                    dynamic prov = provider;
                    foreach (var item in prov.Results)
                    {
                        result.Add(item as ISearchResultBase);
                    }
                }
            }

            return result;
        }
    }
}
