/// <summary>
        /// AJAX to this method to update existing groups with students
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public async Task<string> UpdateGroup(CohortActionObject obj)
        {
            try
            {
                var cs = new CohortService(Session["access_token"].ToString());
                var cohort = UpdateCohort(cs, obj.cohort); //1) update cohort
                var newStudentsAssociations = CreateMultipleAssociation(cs, obj.cohort.id, obj.studentsToCreate); //2) create student cohort association
                var cohortCustom = cs.UpdateCohortCustom(obj.cohort.id, JsonConvert.SerializeObject(obj.custom)); //3) update cohort custom entity

                //Get a list of the current studentCohortAssociations so that we have the ids to delete them from group
                var currentStudentCohortAssociation = await cs.GetStudentCohortAssociationsByCohortId(obj.cohort.id);
                //get the studentCohortAssociationId for students to delete
                var associationToDelete = (from s in obj.studentsToDelete select (from csca in currentStudentCohortAssociation where csca.studentId == s.id select csca.id).Single());
                //delete the studentCohortAssociation
                var removeStudents = DeleteMultipleAssociation(cs, associationToDelete); 

                await Task.WhenAll(newStudentsAssociations, cohortCustom, removeStudents);

                return "Success";
            }
            catch (Exception e)
            {
                //handle
                throw;
            }
            
        }
        internal string CURRENT_ED_ORG_ID = ConfigurationManager.AppSettings["CurrentEdgOrgId"]; //there's no data from inBloom about the current user Ed Org, temporarily using a constant value for each environment

        /// <summary>
        /// Create new student cohort associations
        /// </summary>
        /// <param name="obj">cohort to create</param>
        /// <param name="cs">cohort service</param>
        /// <returns>result of this action</returns>
        public static Task<IEnumerable<ActionResponseResult>> GetNewStudentCohortAssociations(CohortActionObject obj, CohortService cs)
        {
            Task<IEnumerable<ActionResponseResult>> newStudentsAssociations;
            if (obj.studentsToCreate != null && obj.studentsToCreate.Count() > 0)
                newStudentsAssociations = CohortActionHelper.CreateMultipleStudentCohortAssociations(cs, obj.cohort.id, obj.studentsToCreate);
            else
                newStudentsAssociations = null;
            return newStudentsAssociations;
        }
 /// <summary>
 /// AJAX to this method to append the lesson plan info to the group (not the lesson plan itself)
 /// </summary>
 /// <param name="obj">data object to update cohort</param>
 /// <returns></returns>
 public ActionResult AttachFile(CohortActionObject obj)
 {
     try
     {
         var cohortResult = ProcessOneCohortFileUpload(obj);
         return Json(cohortResult, JsonRequestBehavior.AllowGet);
     }
     catch (Exception e)
     {
         //handle
         throw;
     }
 }
        /// <summary>
        /// AJAX to this method to create brand new groups with students
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public async Task<string> CreateGroup(CohortActionObject obj)
        {
            try
            {
                var cs = new CohortService(Session["access_token"].ToString());
                var cohortId = await CreateCohort(cs, obj.cohort); //1) create the cohort first and retrieve the Id of the new cohort
                var studentsAssociations = CreateMultipleAssociation(cs, cohortId, obj.studentsToCreate); //2) start creating student cohort association
                var cohortCustom = cs.CreateCohortCustom(cohortId, JsonConvert.SerializeObject(obj.custom)); //3) initial populate of the cohort custom entity

                await Task.WhenAll(studentsAssociations, cohortCustom);

                return cohortId;
            }
            catch (Exception e)
            {
                //handle
                throw;
            }            
        }
 public static async Task<Task<IEnumerable<ActionResponseResult>>> DeleteStudentCohortAssocations(CohortActionObject obj, CohortService cs)
 {
     Task<IEnumerable<ActionResponseResult>> removeStudents;
     //Get a list of the current studentCohortAssociations so that we have the ids to delete them from group
     var currentStudentCohortAssociation = await cs.GetStudentCohortAssociationsByCohortId(obj.cohort.id);
     //get the studentCohortAssociationId for students to delete
     var associationToDelete = (from s in obj.studentsToDelete
                                select (currentStudentCohortAssociation.FirstOrDefault(csca => csca.studentId == s)));
     //delete the studentCohortAssociation
     removeStudents = CohortActionHelper.DeleteMultipleStudentCohortAssociations(cs, associationToDelete);
     return removeStudents;
 }
 /// <summary>
 /// Update cohort custom entity
 /// </summary>
 /// <param name="obj">Cohort data to update</param>
 /// <param name="cs">Cohort Service object to update</param>
 /// <returns></returns>
 public static Task<HttpResponseMessage> UpdateCustom(CohortActionObject obj, CohortService cs)
 {
     var custom = obj.custom;
     if (custom == null) custom = new CohortCustom { lastModifiedDate = DateTime.UtcNow };
     else custom.lastModifiedDate = DateTime.UtcNow;
     var cohortCustom = cs.UpdateCohortCustom(obj.cohort.id, JsonConvert.SerializeObject(custom));
     return cohortCustom;
 }
        private static async Task ProcessASuccessfulCohortCreate(CohortActionObject obj, CohortService cs, Result cohortResult, string staffId)
        {
            obj.cohort.id = cohortResult.objectActionResult.objectId;
            obj.custom.cohortId = obj.cohort.id;
            //1) start creating staff/student cohort association
            var newStudentsAssociations = CohortActionHelper.GetNewStudentCohortAssociations(obj, cs);
            var newStaffAssociation = CohortActionHelper.CreateOneStaffCohortAssociation(cs, obj.cohort.id, staffId);
            //2) initial populate of the cohort custom entity        
            var cohortCustom = CohortActionHelper.CreateCustom(obj.custom, cs);

            //contruct a list of tasks we're waiting for
            var tasksToWaitFor = new List<Task>();
            if (newStudentsAssociations != null) tasksToWaitFor.Add(newStudentsAssociations);
            if (cohortCustom != null) tasksToWaitFor.Add(cohortCustom);
            if (newStaffAssociation != null) tasksToWaitFor.Add(newStaffAssociation);

            await Task.WhenAll(tasksToWaitFor);

            if (newStudentsAssociations != null)
                CohortActionHelper.DetermineFailedToCreateFor(cohortResult, newStudentsAssociations.Result);

            //determine whether custom was created successfully
            CohortActionHelper.ProcessCustomResult(cohortResult, cohortCustom, HttpStatusCode.Created);
        }
        /// <summary>
        /// Create one cohort
        /// </summary>
        /// <param name="obj">data object to create cohort</param>
        /// <returns>result of the action</returns>
        public async Task<Result> ProcessOneCohortCreate(CohortActionObject obj)
        {
            try
            {
                var accessToken = Session["access_token"];
                if (accessToken != null)
                {
                    var cs = new CohortService(accessToken.ToString());
                    //create the cohort first
                    var cohortResult = await CreateCohort(cs, obj.cohort);

                    //if cohort was created successfully then continue to create associations
                    if (cohortResult.completedSuccessfully)
                    {
                        var staffId = Session[INBLOOM_USER_ID].ToString();
                        await ProcessASuccessfulCohortCreate(obj, cs, cohortResult, staffId);
                    }

                    return cohortResult;
                }
                else
                {
                    //section expired
                    return GlobalHelper.GetSessionExpiredResult(obj.cohort.cohortIdentifier);
                }

            }
            catch (Exception e)
            {
                return GlobalHelper.GetExceptionResult(obj.cohort.cohortIdentifier, e);
            }
        }
        /// <summary>
        /// Update one cohort
        /// </summary>
        /// <param name="obj">data object to update cohort</param>
        /// <returns>result of the action</returns>
        public async Task<Result> ProcessOneCohortUpdate(CohortActionObject obj)
        {
            try
            {
                var accessToken = Session["access_token"];
                if (accessToken != null)
                {
                    var cs = new CohortService(accessToken.ToString());
                    //1) update cohort
                    var cohortResult = await UpdateCohort(cs, obj.cohort);
                    //2) create student cohort association                    
                    var newStudentsAssociations = CohortActionHelper.GetNewStudentCohortAssociations(obj, cs);
                    //3) update cohort custom entity
                    var cohortCustom = CohortActionHelper.UpdateCustom(obj, cs);

                    // if there is no lesson plan, then delete the group's directory from the FTP server
                    if (obj.custom.lessonPlan == null)
                    {
                        FTPHelper.removeDir(obj.cohort.id);
                    }

                    //4) remove students from cohort
                    Task<IEnumerable<ActionResponseResult>> removeStudents;
                    if (obj.studentsToDelete != null && obj.studentsToDelete.Count() > 0)
                        removeStudents = await CohortActionHelper.DeleteStudentCohortAssocations(obj, cs);
                    else
                        removeStudents = null;

                    //contruct a list of tasks we're waiting for
                    var tasksToWaitFor = new List<Task>();
                    if (newStudentsAssociations != null) tasksToWaitFor.Add(newStudentsAssociations);
                    if (cohortCustom != null) tasksToWaitFor.Add(cohortCustom);
                    if (removeStudents != null) tasksToWaitFor.Add(removeStudents);

                    await Task.WhenAll(tasksToWaitFor);

                    if (newStudentsAssociations != null) CohortActionHelper.DetermineFailedToCreateFor(cohortResult, newStudentsAssociations.Result);
                    if (removeStudents != null) CohortActionHelper.DetermineFailedToDeleteFor(cohortResult, removeStudents.Result);

                    //determine whether custom was created successfully
                    CohortActionHelper.ProcessCustomResult(cohortResult, cohortCustom, HttpStatusCode.NoContent, obj.custom, cs);

                    //remove cohort from cache after an update
                    HttpContext.Cache.Remove(obj.cohort.id);

                    return cohortResult;
                }
                else
                {
                    //session expired
                    return GlobalHelper.GetSessionExpiredResult(obj.cohort.id);
                }
            }
            catch (Exception e)
            {
                return GlobalHelper.GetExceptionResult(obj.cohort.id, e);
            }

        }
 /// <summary>
 /// AJAX to this method to update an existing group
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public async Task<ActionResult> UpdateGroup(CohortActionObject obj)
 {
     try
     {
         var cohortResult = await ProcessOneCohortUpdate(obj);
         return Json(cohortResult, JsonRequestBehavior.AllowGet);
     }
     catch (Exception e)
     {
         //handle
         throw;
     }
 }
        public async Task<ActionResult> UploadFiles()
        {
            try
            {
                var accessToken = Session["access_token"];
                if (accessToken != null)
                {
                    var results = new List<ViewDataUploadFilesResult>();
                    var groupIds = Request["groupId"].Split(',');
                    var files = Request.Files;

                    for (int i = 0; i < groupIds.Length; i++)
                    {
                        string groupId = groupIds[i];
                        bool isSuccess = false;
                        ViewDataUploadFilesResult res = new ViewDataUploadFilesResult() { CohortId = groupId };
                        try
                        {
                            HttpPostedFileBase hpf = files[i];
                            // IE passes in the entire path, so we got to make sure we only grab the file name
                            int startIdx = hpf.FileName.LastIndexOf("\\");
                            string fileName = startIdx < 0 ? hpf.FileName : hpf.FileName.Substring(startIdx + 1);
                            string filePath = string.Format("/{0}", fileName);
                            FTPHelper.uploadFileFromStream(groupId, filePath, hpf.InputStream);
                            isSuccess = true;

                            // update the cohort custom 
                            var cs = new CohortService(accessToken.ToString());
                            var cohort = CohortHelper.GetGroupById(accessToken.ToString(), groupId);
                            var group = CohortHelper.GetCohortDisplayObject(cs, cohort).Result;
                            var cohortActionObj = new CohortActionObject()
                            {
                                cohort = cohort,
                                custom = group.custom
                            };
                            // attach the lesson plan info
                            cohortActionObj.custom.lessonPlan = new LessonPlan()
                            {
                                name = fileName,
                                type = hpf.ContentType
                            };

                            var result = await ProcessOneCohortUpdate(cohortActionObj);

                            isSuccess = result.customActionResult.isSuccess;
                            res.Name = fileName;
                            res.Type = hpf.ContentType;
                            res.Length = hpf.ContentLength;
                            res.isSuccess = isSuccess;
                        }
                        catch (Exception ex)
                        {
                            res.isSuccess = false;
                        }

                        results.Add(res);
                    }

                    // Returns json
                    return Json(results, "text/html", System.Text.Encoding.UTF8);
                    //Content("{\"name\":\"" + results[0].Name + "\",\"type\":\"" + results[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", results[0].Length) + "\"}", "text/plain");
                }
            }
            catch (Exception e)
            {
                throw e;
            }

            // add error message
            return null;
        }
        /// <summary>
        /// Update one cohort custom
        /// </summary>
        /// <param name="obj">data object to update cohort</param>
        /// <returns>result of the action</returns>
        public async Task<Result> ProcessOneCohortFileUpload(CohortActionObject obj)
        {
            try
            {
                var accessToken = Session["access_token"];
                if (accessToken != null)
                {
                    var cohortResult = new Result();

                    var cs = new CohortService(accessToken.ToString());
                    // update cohort custom entity
                    var cohortCustom = CohortActionHelper.UpdateCustom(obj, cs);

                    var tasksToWaitFor = new List<Task>();                    
                    tasksToWaitFor.Add(cohortCustom);                    

                    await Task.WhenAll(tasksToWaitFor);
                 
                    //determine whether custom was created successfully
                    CohortActionHelper.ProcessCustomResult(cohortResult, cohortCustom, HttpStatusCode.NoContent, obj.custom, cs);

                    //remove cohort from cache after an update
                    HttpContext.Cache.Remove(obj.cohort.id);

                    return cohortResult;
                }
                else
                {
                    //session expired
                    return GlobalHelper.GetSessionExpiredResult(obj.cohort.id);
                }
            }
            catch (Exception e)
            {
                return GlobalHelper.GetExceptionResult(obj.cohort.id, e);
            }

        }