using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public static class SharedQueries
{

    /// <summary>
    /// Gets the NewsItems based on query string tag argument. Can be used for AND, OR and single tag based search as well as with no tag.
    /// </summary>
    /// <param name="tagParam">The query string argument for tags (usually "tag"). '+' in the URL stands for AND, "|" stands for OR</param>
    /// <param name="dc">The data context against which the query will be built.</param>
    /// <returns></returns>
    public static IQueryable<NewsItem> GetNewsItemsByTags(string tagParam, BlogNETDataContext dc)
    {
        
        if (tagParam != null && tagParam.Contains('|'))
        {
            string[] tagsToMatch = tagParam.Split('|');
            //prevent duplicate tags and reduce the number of tags
            //to prevent too much load on the SQL Server and eventual DoS attack
            tagsToMatch = tagsToMatch.Take(15).Distinct().ToArray();

            return from ni in dc.NewsItems
                   orderby ni.PostDate descending
                   where ni.Tags.Any<Tag>(t => tagsToMatch.Contains(t.TagValue))
                   select ni;
        }
        else if (tagParam != null && tagParam.Contains(' '))
        {
            string[] tagsToMatch = tagParam.Split(' ');
            tagsToMatch = tagsToMatch.Take(15).Distinct().ToArray();

            return from res in
                       (from tag in dc.Tags
                        where tagsToMatch.Contains(tag.TagValue)
                        group tag.NewsItem by tag.NewsItem into newsItems
                        select newsItems)
                   orderby res.Key.PostDate descending
                   where res.Count() == tagsToMatch.Length
                   select res.Key;
        }
        else
        {
            return from ni in dc.NewsItems
                   orderby ni.PostDate descending
                   where tagParam == null ? true :
                   ni.Tags.Any<Tag>(t => t.TagValue == tagParam)
                   select ni;
        }
    }

}
