using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using NorthwindModel;
using System.Runtime.Serialization;
using System.IO;

[ServiceContract(Namespace = "")]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Products
{

    /// <summary>
    /// Reads the available products to provide data for the Kendo Grid
    /// </summary>
    /// <returns>All available products</returns>
    [OperationContract]
    [WebInvoke( ResponseFormat = WebMessageFormat.Json,
                  RequestFormat = WebMessageFormat.Json)]    
    public DataSourceResult Read(int skip, int take, IEnumerable<Sort> sort, Filter filter)
    {
        MapDescriptors(filter, sort, new Dictionary<string, string>() { { "CategoryName", "Category.CategoryName" } });

        using (var northwind = new Northwind())
        {
            var result = northwind.Products
                .OrderBy(p => p.ProductID)
                .ToDataSourceResult(take, skip, sort, filter, p => new ProductViewModel
                {
                    ProductID = p.ProductID,
                    ProductName = p.ProductName,
                    CategoryName = p.Category.CategoryName
                });

            return result;
        }
    }

    private void MapDescriptors(Filter filter, IEnumerable<Sort> sort, Dictionary<string, string> mapping)
    {
        if (filter != null)
        {
            var filterQueue = new Queue<Filter>();
            Filter current;
            filterQueue.Enqueue(filter);            
            while (filterQueue.Count > 0)
            {
                current = filterQueue.Dequeue();
                if (current.Field != null && mapping.ContainsKey(current.Field))
                {
                    current.Field = mapping[current.Field];
                }
                if (current.Filters != null)
                {
                    foreach (var item in current.Filters)
                    {
                        filterQueue.Enqueue(item);
                    }     
                }              
            }		 
        }

        if (sort != null)
        {
            foreach (var item in sort)
            {
                if (mapping.ContainsKey(item.Field))
                {
                    item.Field = mapping[item.Field];
                }
            }
        }
    }
}
