<#@ template language="C#" HostSpecific="True" #>
<#@ output extension="cs" #>
<#@ include file="..\..\ControllerHead.include.t4" #>
using Microsoft.AspNet.Mvc;
using Microsoft.Data.Entity;
using System.Data.SqlClient;

// This code was generated by C1 Scaffolder.

<#
	var columns = Options["Columns"];
#>
namespace <#= Namespace #>
{
    public partial class <#= ControllerName #> : Controller
    {
        private <#= DbContextTypeName #> db;

        public <#= ControllerName #>(<#= DbContextTypeName #> context)
        {
            db = context;
        }

        public ActionResult <#= ViewName #>()
        {
            var model = db.<#= EntitySetName #>;
<#@ include file="..\..\DataMapViewBag.include.t4" #>
            return View(model);
        }

<#
	var primaryKeys = "";
	if(PrimaryKeys != null && PrimaryKeys.Count > 0)
	{
		primaryKeys = string.Join(", ", PrimaryKeys.Select(p => "item." + p.Key));
	}

	// ReadActionUrl
	if(!string.IsNullOrEmpty(Options["ReadActionUrl"]))
	{
#>
        public ActionResult <#= Options["ReadActionUrl"] #>([C1JsonRequest] CollectionViewRequest<<#= ViewDataTypeName #>> requestData)
        {
            return this.C1Json(CollectionViewHelper.Read(requestData, db.<#= EntitySetName #>));
        }

<#
	}

	// CreateActionUrl
	if(!string.IsNullOrEmpty(Options["CreateActionUrl"]) && Options["AllowAddNew"] && !Options["BatchEdit"])
	{
#>
        public ActionResult <#= Options["CreateActionUrl"] #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return Create(requestData, db.<#= EntitySetName #>);
        }

        private ActionResult Create<T>(CollectionViewEditRequest<T> requestData, DbSet<T> data) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    data.Add(item);
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    error = GetExceptionMessage(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// UpdateActionUrl
	if(!string.IsNullOrEmpty(Options["UpdateActionUrl"]) && Options["AllowEdit"] && !Options["BatchEdit"])
	{
#>
        public ActionResult <#= Options["UpdateActionUrl"] #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return Update(requestData, db.<#= EntitySetName #>);
        }

        private ActionResult Update<T>(CollectionViewEditRequest<T> requestData, DbSet<T> data) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    db.Entry(item as object).State = EntityState.Modified;
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    error = GetExceptionMessage(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// DeleteActionUrl
	if(!string.IsNullOrEmpty(Options["DeleteActionUrl"]) && Options["AllowDelete"] && !Options["BatchEdit"])
	{
#>
        public ActionResult <#= Options["DeleteActionUrl"] #>([C1JsonRequest]CollectionViewEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            return Delete(requestData, db.<#= EntitySetName #>, item => new object[] { <#= primaryKeys #> });
        }

        private ActionResult Delete<T>(CollectionViewEditRequest<T> requestData, DbSet<T> data, Func<T, object[]> getKeys) where T : class
        {
            return this.C1Json(CollectionViewHelper.Edit<T>(requestData, item =>
            {
                string error = string.Empty;
                bool success = true;
                try
                {
                    var resultItem = data.FirstOrDefault(dataItem => ArrayToString(getKeys(dataItem)) == ArrayToString(getKeys(item)));
                    data.Remove(resultItem);
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    error = GetExceptionMessage(e);
                    success = false;
                }
                return new CollectionViewItemResult<T>
                {
                    Error = error,
                    Success = success,
                    Data = item
                };
            }, () => data.ToList<T>()));
        }

<#
	}

	// BatchEditActionUrl
	if(!string.IsNullOrEmpty(Options["BatchEditActionUrl"]) && Options["BatchEdit"])
	{
#>
        public ActionResult <#= Options["BatchEditActionUrl"] #>([C1JsonRequest]CollectionViewBatchEditRequest<<#= ViewDataTypeName #>> requestData)
        {
            Func<<#= ViewDataTypeName #>, object[]> getKeys = item => new object[] { <#= primaryKeys #> };
            return this.C1Json(CollectionViewHelper.BatchEdit(requestData, batchData =>
            {
                var itemresults = new List<CollectionViewItemResult<<#= ViewDataTypeName #>>>();
                string error = string.Empty;
                bool success = true;
                try
                {
                    if (batchData.ItemsCreated != null)
                    {
                        batchData.ItemsCreated.ToList().ForEach(st =>
                        {
                            db.<#= EntitySetName #>.Add(st);
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = st
                            });
                        });
                    }
                    if (batchData.ItemsDeleted != null)
                    {
                        batchData.ItemsDeleted.ToList().ForEach(item =>
                        {
                            var fItem = db.<#= EntitySetName #>.FirstOrDefault(dataItem => ArrayToString(getKeys(dataItem)) == ArrayToString(getKeys(item)));
                            db.<#= EntitySetName #>.Remove(fItem);
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = item
                            });
                        });
                    }
                    if (batchData.ItemsUpdated != null)
                    {
                        batchData.ItemsUpdated.ToList().ForEach(item =>
                        {
                            db.Entry(item).State = EntityState.Modified;
                            itemresults.Add(new CollectionViewItemResult<<#= ViewDataTypeName #>>
                            {
                                Error = "",
                                Success = success,
                                Data = item
                            });
                        });
                    }
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    error = GetExceptionMessage(e);
                    success = false;
                }
 
                return new CollectionViewResponse<<#= ViewDataTypeName #>>
                {
                    Error = error,
                    Success = success,
                    OperatedItemResults = itemresults
                };
            }, () => db.<#= EntitySetName #>.ToList()));
        }

<#
	}

	if(Options["AllowAddNew"] || Options["AllowEdit"] || Options["AllowDelete"] ||
		Options["BatchEdit"])
	{
	#>
        /// <summary>
        /// In order to get the real exception message.
        /// </summary>
        private static SqlException GetSqlException(Exception e)
        {
            while(e != null && !(e is SqlException))
            {
                e = e.InnerException;
            }
            return e as SqlException;
        }

        // Get the real exception message
        internal static string GetExceptionMessage(Exception e)
        {
            var msg = e.Message;
            var sqlException = GetSqlException(e);
            if (sqlException != null)
            {
                msg = sqlException.Message;
            }
            return msg;
        }
	<# 
		if(Options["AllowDelete"] || Options["BatchEdit"]){
		#>

        /// <summary>
        /// Get string from object array.
        /// </summary>
        /// <param name="array">the object array</param>
        /// <returns>the string value</returns>
        private static string ArrayToString(object[] array)
        {
            if (array != null)
            {
                return string.Join(",", array.Cast<object>().Select(a => a.ToString()));
            }
            return "";
        }
<#
		}
	}
#>
<#@ include file="..\..\DataMapAction.include.t4" #>
    }
}