private void AddCheckersToProblemViewModel(ViewModelType problem) =>
 problem.AvailableCheckers = this.checkersData
                             .GetAll()
                             .Select(checker => new SelectListItem
 {
     Text  = checker.Name,
     Value = checker.Name
 });
        private bool IsValidProblem(ViewModelType model)
        {
            var isValid = true;

            if (model.SubmissionTypes == null || !model.SubmissionTypes.Any(s => s.IsChecked))
            {
                this.ModelState.AddModelError(nameof(model.SelectedSubmissionTypes), GlobalResource.Select_one_submission_type);
                isValid = false;
            }

            return(isValid);
        }
        private ViewModelType PrepareProblemViewModelForCreate(Contest contest)
        {
            var problem = new ViewModelType
            {
                ContestId   = contest.Id,
                ContestName = contest.Name,
                OrderBy     = this.problemsData.GetNewOrderByContest(contest.Id)
            };

            this.AddCheckersAndProblemGroupsToProblemViewModel(
                problem,
                contest.ProblemGroups.Count,
                contest.IsOnline);

            problem.SubmissionTypes = this.submissionTypesData
                                      .GetAll()
                                      .Select(SubmissionTypeViewModel.ViewModel)
                                      .ToList();

            return(problem);
        }
        private void AddCheckersAndProblemGroupsToProblemViewModel(
            ViewModelType problem,
            int numberOfProblemGroups,
            bool isOnlineContest)
        {
            problem.AvailableCheckers = this.checkersData
                                        .GetAll()
                                        .Select(checker => new SelectListItem
            {
                Text     = checker.Name,
                Value    = checker.Name,
                Selected = checker.Name.Contains("Trim")
            });

            if (isOnlineContest && numberOfProblemGroups > 0)
            {
                this.ViewBag.ProblemGroupIdData = this.problemGroupsData
                                                  .GetAllByContest(problem.ContestId)
                                                  .OrderBy(pg => pg.OrderBy)
                                                  .Select(DropdownViewModel.FromProblemGroup);
            }

            this.ViewBag.ProblemGroupTypeData = DropdownViewModel.GetEnumValues <ProblemGroupType>();
        }
        public ActionResult Edit(int id, ViewModelType problem)
        {
            if (!this.CheckIfUserHasProblemPermissions(id))
            {
                return(this.RedirectToContestsAdminPanelWithNoPrivilegesMessage());
            }

            var existingProblem = this.problemsData.GetWithProblemGroupById(id);

            if (existingProblem == null)
            {
                this.TempData.Add(GlobalConstants.DangerMessage, GlobalResource.Problem_not_found);
                return(this.RedirectToAction(c => c.Index()));
            }

            if (problem == null)
            {
                problem = this.PrepareProblemViewModelForEdit(id);

                this.AddCheckersToProblemViewModel(problem);

                return(this.View(problem));
            }

            if (problem.AdditionalFiles != null && problem.AdditionalFiles.ContentLength != 0)
            {
                this.ValidateUploadedFile(nameof(problem.AdditionalFiles), problem.AdditionalFiles);
            }

            if (!this.ModelState.IsValid)
            {
                problem = this.PrepareProblemViewModelForEdit(id);

                this.AddCheckersToProblemViewModel(problem);

                this.submissionTypesData
                .GetAll()
                .Select(SubmissionTypeViewModel.ViewModel)
                .ForEach(SubmissionTypeViewModel.ApplySelectedTo(problem));

                return(this.View(problem));
            }

            existingProblem                  = problem.GetEntityModel(existingProblem);
            existingProblem.Checker          = this.checkersData.GetByName(problem.Checker);
            existingProblem.SolutionSkeleton = problem.SolutionSkeletonData;
            existingProblem.SubmissionTypes.Clear();
            existingProblem.ProblemGroup.Type = ((ProblemGroupType?)problem.ProblemGroupType).GetValidTypeOrNull();

            if (!existingProblem.ProblemGroup.Contest.IsOnline)
            {
                existingProblem.ProblemGroup.OrderBy = problem.OrderBy;
            }

            if (problem.AdditionalFiles != null && problem.AdditionalFiles.ContentLength != 0)
            {
                using (var archiveStream = new MemoryStream())
                {
                    problem.AdditionalFiles.InputStream.CopyTo(archiveStream);
                    existingProblem.AdditionalFiles = archiveStream.ToArray();
                }
            }

            problem.SubmissionTypes.ForEach(s =>
            {
                if (s.IsChecked && s.Id.HasValue)
                {
                    var submission = this.submissionTypesData.GetById(s.Id.Value);
                    existingProblem.SubmissionTypes.Add(submission);
                }
            });

            this.problemsData.Update(existingProblem);

            this.TempData.AddInfoMessage(GlobalResource.Problem_edited);
            return(this.RedirectToAction(c => c.Index(existingProblem.ProblemGroup.ContestId)));
        }
        public ActionResult Create(int id, ViewModelType problem)
        {
            if (!this.CheckIfUserHasContestPermissions(id))
            {
                return(this.RedirectToContestsAdminPanelWithNoPrivilegesMessage());
            }

            var contest = this.contestsData.GetById(id);

            if (contest == null)
            {
                this.TempData.AddDangerMessage(GlobalResource.Invalid_contest);
                return(this.RedirectToAction(c => c.Index()));
            }

            if (problem == null)
            {
                problem = this.PrepareProblemViewModelForCreate(contest);

                this.AddCheckersToProblemViewModel(problem);

                return(this.View(problem));
            }

            if (problem.Resources != null && problem.Resources.Any())
            {
                var validResources = problem.Resources
                                     .All(res => !string.IsNullOrEmpty(res.Name) &&
                                          ((res.Type == ProblemResourceType.AuthorsSolution && res.File != null && res.File.ContentLength > 0) ||
                                           (res.Type == ProblemResourceType.ProblemDescription && res.File != null && res.File.ContentLength > 0) ||
                                           (res.Type == ProblemResourceType.Link && !string.IsNullOrEmpty(res.Link))));

                if (!validResources)
                {
                    this.ModelState.AddModelError("Resources", GlobalResource.Resources_not_complete);
                }
            }

            if (problem.AdditionalFiles != null && problem.AdditionalFiles.ContentLength != 0)
            {
                this.ValidateUploadedFile(nameof(problem.AdditionalFiles), problem.AdditionalFiles);
            }

            if (problem.Tests != null && problem.Tests.ContentLength != 0)
            {
                this.ValidateUploadedFile(nameof(problem.Tests), problem.Tests);
            }

            if (!this.IsValidProblem(problem) || !this.ModelState.IsValid)
            {
                this.AddCheckersToProblemViewModel(problem);
                return(this.View(problem));
            }

            var newProblem = problem.GetEntityModel();

            newProblem.Checker = this.checkersData.GetByName(problem.Checker);

            problem.SubmissionTypes.ForEach(s =>
            {
                if (s.IsChecked && s.Id.HasValue)
                {
                    var submission = this.submissionTypesData.GetById(s.Id.Value);
                    newProblem.SubmissionTypes.Add(submission);
                }
            });

            if (problem.SolutionSkeletonData != null && problem.SolutionSkeletonData.Any())
            {
                newProblem.SolutionSkeleton = problem.SolutionSkeletonData;
            }

            if (problem.Resources != null && problem.Resources.Any())
            {
                this.AddResourcesToProblem(newProblem, problem.Resources);
            }

            if (problem.AdditionalFiles != null && problem.AdditionalFiles.ContentLength != 0)
            {
                newProblem.AdditionalFiles = problem.AdditionalFiles.ToByteArray();
            }

            if (problem.Tests != null && problem.Tests.ContentLength != 0)
            {
                try
                {
                    this.AddTestsToProblem(newProblem, problem.Tests);
                }
                catch (Exception ex)
                {
                    // TempData is not working with return this.View
                    var systemMessages = new SystemMessageCollection
                    {
                        new SystemMessage
                        {
                            Content    = string.Format(GlobalResource.Tests_cannot_be_improrted, ex.Message),
                            Type       = SystemMessageType.Error,
                            Importance = 0
                        }
                    };

                    this.ViewBag.SystemMessages = systemMessages;

                    this.AddCheckersToProblemViewModel(problem);

                    return(this.View(problem));
                }
            }

            if (newProblem.ProblemGroupId == default(int))
            {
                newProblem.ProblemGroup = new ProblemGroup
                {
                    ContestId = contest.Id,
                    OrderBy   = newProblem.OrderBy,
                    Type      = ((ProblemGroupType?)problem.ProblemGroupType).GetValidTypeOrNull()
                };
            }

            this.problemsData.Add(newProblem);

            this.TempData.AddInfoMessage(GlobalResource.Problem_added);
            return(this.RedirectToAction("Problem", "Tests", new { newProblem.Id }));
        }