<!--
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
-->

<%@ ServiceHost Language="C#" Factory="Microsoft.OData.Service.DataServiceHostFactory, Microsoft.OData.Service, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Service="DataJS.Tests.V4.FoodStoreDataService" %>

namespace DataJS.Tests.V4
{
    using System;
    using System.Collections.Generic;
    using Microsoft.OData.Service;
    using Microsoft.OData.Service.Providers;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Web;
    using System.IO;
    using Microsoft.Spatial;
    
    /// <summary>
    /// Provides a service similar to FoodStoreDataService, but uses V4 and WCF Data Services 6.0.0-beta1
    /// features.
    /// </summary>
    [System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class FoodStoreDataService : DataService<FoodContainer>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
            config.UseVerboseErrors = true;
            // Set Foods page size to 5 for cache testing
            config.SetEntitySetPageSize("Foods", 5);
            // Make the Categories set paged to have a paged feed
            config.SetEntitySetPageSize("Categories", 1);
        }
        
        [WebInvoke]
        public string ResetData()
        {
            this.CurrentDataSource.ResetData();
            return "Data Reset";
        }

        [WebGet]
        public IQueryable<string> FoodsAvailable()
        {
            return this.CurrentDataSource.Foods.Select(food => food.Name);
        }

        [WebGet]
        public IQueryable<Package> PackagingTypes()
        {
            return this.CurrentDataSource.Foods.Select(food => food.Packaging);
        }

        [WebGet]
        public string UserNameAndPassword()
        {
            var request = WebOperationContext.Current.IncomingRequest;
            string authorization = request.Headers["Authorization"];
            if (String.IsNullOrEmpty(authorization))
            {
                WebOperationContext.Current.OutgoingResponse.Headers["WWW-Authenticate"] = "Basic realm=\"localhost\"";
                throw new DataServiceException(401, "Access denied in UserNameAndPassword");
            }

            return authorization;
        }
    }

    public class FoodContainer : ReflectionDataContext, IUpdatable, IDataServiceStreamProvider2
    {
        private static bool dataInitialized;

        public IQueryable<Category> Categories
        {
            get { return this.GetResourceSetEntities<Category>("Categories").AsQueryable(); }
        }
        
        public IQueryable<Food> Foods
        {
            get { return this.GetResourceSetEntities<Food>("Foods").AsQueryable(); }
        }

        public void ResetData()
        {
            this.ClearData();

            var builder = SpatialImplementation.CurrentImplementation.CreateBuilder();
            builder.GeometryPipeline.SetCoordinateSystem(CoordinateSystem.DefaultGeography);
            builder.GeometryPipeline.BeginGeometry(SpatialType.Collection);
            builder.GeometryPipeline.BeginFigure(new GeometryPosition(5.0, 5.0));
            builder.GeometryPipeline.EndFigure();
            builder.GeometryPipeline.EndGeometry();
            
            int i = 0;
            Category[] categories = new Category[]
            {
                new Category { CategoryID = i++, Name = "Baking Supplies" },
                new Category { CategoryID = i++, Name = "Condiments" },
                new Category { CategoryID = i++, Name = "Empty Category" }
            };
            Array.ForEach(categories, (category) => this.GetResourceSetEntities<Category>("Categories").Add(category));
            
            i = 0;
            Food[] foods = new Food[]
            {            
                new Food()
                {
                    FoodID = i++,
                    Name = "flour",
                    UnitPrice = .19999,
                    ServingSize = 1,
                    MeasurementUnit = "Cup",
                    ProteinGrams = 3,
                    FatGrams = 1,
                    CarbohydrateGrams = 20,
                    CaloriesPerServing = 140,
                    IsAvailable = true,
                    ExpirationDate = new DateTime(2010, 12, 25, 12, 0, 0),
                    ItemGUID = new Guid("27272727272727272727272727272727"),
                    Weight = 10f,
                    AvailableUnits = 1,
                    
                    Packaging = new Package(){
                        Type = null, 
                        Color = String.Empty, 
                        NumberPerPackage = int.MaxValue, 
                        RequiresRefridgeration = false, 
                        PackageDimensions = new Dimensions()
                        {
                            Length = Decimal.MaxValue, 
                            Height = Int16.MaxValue, 
                            Width = Int64.MaxValue, 
                            Volume = double.MaxValue,   
                        },
                        ShipDate = new DateTime(2000, 12, 29)
                    },
                    
                    CookedSize = new CookedDimensions()
                    {
                        Height = 1,
                        Length = 2,
                        Width = 3,
                        Volume = 1 * 2 * 3
                    },
                    
                    Category = categories[0],
                    
                    AlternativeNames = new List<string>() {"ground cereal", "ground grain"},
                    
                    Providers = new List<Provider> {
                        new Provider() { 
                             Name= "Flour Provider", 
                             Aliases = new List<string>() {"fp1", "flour provider1"},
                             Details = new ProviderDetails() {
                                 Telephone= "555-555-555",
                                 PreferredCode = 1001
                             }
                        },
                        new Provider() { 
                             Name= "Ground Grains", 
                             Aliases = new List<string>()
                        }
                    },
                    
                    SpatialData = (GeometryCollection)builder.ConstructedGeometry 
                },
                
                new Food()
                {
                    FoodID = i++,
                    Name = "sugar",
                    UnitPrice = .2,
                    ServingSize = 1,
                    MeasurementUnit = "tsp",
                    ProteinGrams = 0,
                    FatGrams = 0,
                    CarbohydrateGrams = 4,
                    CaloriesPerServing = 16,
                    IsAvailable = false,
                    ExpirationDate = new DateTime(2011, 12, 28),
                    ItemGUID = new Guid("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
                    Weight = 0.1f,
                    AvailableUnits = 0,

                    Packaging = new Package(){
                        Type = " ",
                        Color = "BLUE",
                        NumberPerPackage = int.MinValue,
                        RequiresRefridgeration = true,
                        PackageDimensions = new Dimensions(){
                            Length = Decimal.MinValue,
                            Height = Int16.MinValue,
                            Width = Int64.MinValue,
                            Volume = double.MinValue,
                        },
                        ShipDate = new DateTime(2000, 12, 29),
                    },
                    
                    Category = categories[1],
                },

                new Food()
                {
                    FoodID = i++,
                    Name = "1 Chicken Egg",
                    UnitPrice = 0.55,
                    MeasurementUnit = null,
                    ServingSize = 1,
                    ProteinGrams = 6,
                    FatGrams = 1,
                    CarbohydrateGrams = 1,
                    CaloriesPerServing = 70,
                    IsAvailable = true,
                    ExpirationDate = new DateTime(2000, 12, 29),
                    ItemGUID = new Guid("00000000000000000000000000000000"),
                    Weight = 0,
                    AvailableUnits = -128,
                    
                    Packaging = new Package(){
                        Type = "18     - Carton",
                        Color = " brown ",
                        NumberPerPackage = 0,
                        RequiresRefridgeration = true,
                        PackageDimensions = null,
                        ShipDate = new DateTime(2000, 12, 29),
                    },
                    
                    Category = null,
                },

                new Food()
                {
                    FoodID = i++,
                    Name = "Brown Sugar",
                    UnitPrice = 1.6,
                    ServingSize = 1,
                    MeasurementUnit = "TSP.",
                    ProteinGrams = 0,
                    FatGrams = 0,
                    CarbohydrateGrams = 5, 
                    CaloriesPerServing = 16,
                    IsAvailable = true,
                    ExpirationDate = new DateTime(2011, 12, 28),
                    ItemGUID = new Guid("0123456789abcdef0123456789abcdef"),
                    Weight = 4.5f,
                    AvailableUnits = 127,
                    Packaging = null,
                    Category = categories[1],
                },
                
                new PreparedFood()
                {
                    FoodID = i++,
                    Name = "Cobb Salad",
                    UnitPrice = 1.99,
                    ServingSize = -1,
                    MeasurementUnit = "cups",
                    ProteinGrams = 6,
                    FatGrams = 1,
                    CarbohydrateGrams = 3, 
                    CaloriesPerServing = 5,
                    IsAvailable = true,
                    ExpirationDate = new DateTime(2000, 12, 29),
                    ItemGUID = new Guid("0123456789abcdef0123456789abcdef"),
                    Weight = 5.674f,
                    AvailableUnits = 127,
                    Packaging = null,
                    Category = categories[1],
                    Instructions = "1.) Open 2.) Eat",
                    NumberOfIngredients = 4,
                },
                
                new PreparedFood()
                {
                    FoodID = i++,
                    Name = "Lasagna",
                    UnitPrice = 0,
                    ServingSize = 8,
                    MeasurementUnit = " servings",
                    ProteinGrams = 100,
                    FatGrams = 4,
                    CarbohydrateGrams = 27, 
                    CaloriesPerServing = 389,
                    IsAvailable = true,
                    ExpirationDate = new DateTime(1904, 2, 29),
                    ItemGUID = new Guid("0123456789abcdef0123456789abcdef"),
                    Weight = 0,
                    AvailableUnits = 4,
                    Packaging = new Package(){
                        Type = "box",
                        Color = " 1 ",
                        NumberPerPackage = 1,
                        RequiresRefridgeration = true,
                        PackageDimensions = new Dimensions(){
                            Length = 3,
                            Height = 1,
                            Width = 5,
                            Volume = 1.5,
                        },
                        ShipDate = new DateTime(2000, 12, 29),
                    },
                    Category = categories[0],
                    Instructions = "Bake in oven",
                    NumberOfIngredients = 15,
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Chocolate"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Pizza"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Avocados"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Quinoa"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Oatmeal"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Peanut Butter"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Banana"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Yam"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Clam"
                },
                
                new Food()
                {                    
                    FoodID = i++,
                    Name = "Spam"
                }
            };
            Array.ForEach(foods, (food) => this.GetResourceSetEntities<Food>("Foods").Add(food));

            categories[0].Foods.Add(foods[0]);
            categories[1].Foods.Add(foods[2]);
            categories[1].Foods.Add(foods[3]);
        }

        protected override void EnsureDataIsInitialized()
        {
            if (!dataInitialized)
            {
                this.ResetData();
                dataInitialized = true;
            }
        }

        public Stream GetReadStream(object entity, ResourceProperty streamProperty, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)
        {
            return new MemoryStream();
        }

        public Uri GetReadStreamUri(object entity, ResourceProperty streamProperty, DataServiceOperationContext operationContext)
        {
            if (streamProperty.Name == "Icon")
            {
                return null;
            }
            return new Uri(operationContext.AbsoluteServiceUri, streamProperty.Name);
        }

        public string GetStreamContentType(object entity, ResourceProperty streamProperty, DataServiceOperationContext operationContext)
        {
            if (streamProperty.Name == "Icon")
            {
                return "image/gif";
            }
            return "image/png";
        }

        public string GetStreamETag(object entity, ResourceProperty streamProperty, DataServiceOperationContext operationContext)
        {
            return "W/\"123456789\"";
        }

        public Stream GetWriteStream(object entity, ResourceProperty streamProperty, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)
        {
            return new MemoryStream();
        }

        public void DeleteStream(object entity, DataServiceOperationContext operationContext)
        {
            // do nothing.
        }

        public Stream GetReadStream(object entity, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public Uri GetReadStreamUri(object entity, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public string GetStreamContentType(object entity, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public string GetStreamETag(object entity, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public Stream GetWriteStream(object entity, string etag, bool? checkETagForEquality, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public string ResolveType(string entitySetName, DataServiceOperationContext operationContext)
        {
            throw new NotImplementedException();
        }

        public int StreamBufferSize
        {
            get { return 1024; }
        }
    }

    /// <summary>
    /// The Category class is a simple class with V1-compatible feed customizations.
    /// </summary>
    public class Category
    {
        public Category()
        {
            this.Foods = new List<Food>();
        }
        
        public int CategoryID { get; set; }
        public string Name { get; set; }
        public List<Food> Foods { get; set; }
    }
    
    /// <summary>
    /// The Food class has a mixture of V1-compatible and incompatible feed
    /// customizations (thus it's V2), and custom mappings.
    /// </summary>
    public class Food
    {
        private List<string> alternativeNames = new List<string>();
        private List<Provider> providers = new List<Provider>();
        
        // Primitive types
        public int FoodID { get; set; }
        public string Name { get; set; }
        public double UnitPrice { get; set; }
        public Decimal ServingSize { get; set; }
        public string MeasurementUnit { get; set; }
        public Byte ProteinGrams { get; set; }
        public Int16 FatGrams { get; set; }
        public Int32 CarbohydrateGrams { get; set; }
        public Int64 CaloriesPerServing { get; set; }
        public Boolean IsAvailable { get; set; }
        public DateTime ExpirationDate { get; set; }
        public Guid ItemGUID { get; set; }
        public Single Weight { get; set; }
        public sbyte AvailableUnits { get; set; }

        // Complex types
        public Package Packaging { get; set; }
        public CookedDimensions CookedSize { get; set; }

        // Navigation properties
        public Category Category { get; set; }

        // Collection properties
        public List<string> AlternativeNames
        {
            get { return alternativeNames; }
            set { alternativeNames = value; }
        }

        public List<Provider> Providers
        {
            get { return providers; }
            set { providers = value; }
        }

        public GeometryCollection SpatialData
        {
            get;
            set;
        }
        
    }

    public class Provider
    {
        public string Name { get; set; }
        public List<string> Aliases { get; set; }
        public ProviderDetails Details { get; set; }
    }

    public class ProviderDetails
    {
        public string Telephone { get; set; }
        public int PreferredCode { get; set; }
    }
    
    public class Package
    {
        public string Type { get; set; }
        public string Color { get; set; }
        public int NumberPerPackage { get; set; }
        public Boolean RequiresRefridgeration { get; set; }
        public DateTime ShipDate { get; set; }
        public Dimensions PackageDimensions { get; set; }
    }

    public class Dimensions
    {
        public Decimal Length { get; set; }
        public Int16 Height { get; set; }
        public Int64 Width { get; set; }
        public double Volume { get; set; }
    }

    public class CookedDimensions
    {
        public Decimal Length { get; set; }
        public Int16 Height { get; set; }
        public Int64 Width { get; set; }
        public double Volume { get; set; }
    }

    public class PreparedFood : Food
    {
        public string Instructions { get; set; }
        public float NumberOfIngredients { get; set; }
    }
}
