private void AddHolds(ExistingProblem problem, CreateProblemRequest newProblem,
                              IEnumerable <Hold> existingHolds, IEnumerable <HoldRule> existingHoldRules)
        {
            if (problem.Holds is null)
            {
                throw new ArgumentException("The problem must have holds.", nameof(problem));
            }

            if (newProblem.Holds is null)
            {
                throw new ArgumentException("The problem must have holds.", nameof(newProblem));
            }

            foreach (var hold in problem.Holds)
            {
                var newHold = new CreateHoldOnProblemRequest()
                {
                    HoldId = existingHolds.First(existingHold => existingHold.Name == hold.Hold).Id,
                    IsStandingStartHold = hold.IsStandingStartHold,
                    ExistingHoldRuleIds = new List <int>(),
                    NewHoldRules        = new List <CreateHoldRuleRequest>()
                };

                AddHoldRules(hold, newHold, existingHoldRules);
                newProblem.Holds.Add(newHold);
            }
        }
        private static void ValiadteHolds(ExistingProblem problem)
        {
            if (problem.Holds is null)
            {
                throw new ArgumentException("The problem must have holds.", nameof(problem));
            }

            var validHoldRegexes = new List <string>()
            {
                "[0-9]{1,3}[A-E]?",
                "any",
                "floor",
                "Arete",
                "Girder",
                "balcony"
            };

            var validHoldRuleRegex = new List <string>()
            {
                "optional",
                "feet only",
                "no undercut",
                "hands only",
                "slope only",
                "top right",
                "top",
                "match",
                "undercut only"
            };

            foreach (var hold in problem.Holds)
            {
                if (hold.Rules is null)
                {
                    continue;
                }

                foreach (string rule in hold.Rules)
                {
                    if (!validHoldRuleRegex.Any(regex => Regex.IsMatch(rule, regex)))
                    {
                        throw new Exception();
                    }
                }

                if (!validHoldRegexes.Any(regex => Regex.IsMatch(hold.Hold, regex)))
                {
                    throw new Exception();
                }
            }
        }
        private void AddRules(ExistingProblem problem, CreateProblemRequest newProblem)
        {
            if (repository.GeneralRule is null)
            {
                throw new DatabaseException();
            }

            foreach (string rule in problem.Rules ?? new List <string>())
            {
                var existingRule = repository.GeneralRule.Local.First(generalRule => generalRule.Name == rule);
                newProblem.ExistingRuleIds = newProblem.ExistingRuleIds.Concat(new List <int>()
                {
                    existingRule.Id
                });
            }
        }
        private static void AddGrades(ExistingProblem problem, CreateProblemRequest newProblem, IEnumerable <TechGrade> techGrades,
                                      IEnumerable <BGrade> bGrades, IEnumerable <FurlongGrade> furlongGrades)
        {
            if (problem.Grades is null)
            {
                throw new ArgumentException("The problem must have grades.", nameof(problem));
            }

            foreach (string grade in problem.Grades)
            {
                if (Regex.IsMatch(grade, "^[4-6][a-c][+-]?$"))
                {
                    if (newProblem.TechGradeId != null)
                    {
                        throw new Exception();
                    }

                    newProblem.TechGradeId = techGrades.First(techGrade => techGrade.Name == grade).Id;
                }
                else if (Regex.IsMatch(grade, "^B[0-8]$"))
                {
                    if (newProblem.BGradeId != null)
                    {
                        throw new Exception();
                    }

                    newProblem.BGradeId = bGrades.First(bGrade => bGrade.Name == grade).Id;
                }
                else if (Regex.IsMatch(grade, "^(AAA)|(XXX)$"))
                {
                    if (newProblem.FurlongGradeId != null)
                    {
                        throw new Exception();
                    }

                    newProblem.FurlongGradeId = furlongGrades.First(furlongGrade => furlongGrade.Name == grade).Id;
                }
                else
                {
                    throw new Exception();
                }
            }
        }
        private static void ValidateName(ExistingProblem problem)
        {
            if (problem.Name is null)
            {
                throw new ArgumentException("The problem must have a name.", nameof(problem));
            }

            if (problem.Name == "“4b or not …”" || problem.Name == "While Inventing a Nice 4b")
            {
                return;
            }

            string[] words = problem.Name.Split(' ');

            foreach (string word in words)
            {
                if (word == "^AAA$" || Regex.IsMatch(word, "^[4-6][a-c][+-]?$") || Regex.IsMatch(word, "^B[0-9]$"))
                {
                    throw new Exception();
                }
            }
        }
        private static void ValidateGrades(ExistingProblem problem)
        {
            if (problem.Grades is null)
            {
                throw new ArgumentException("The problem must have grades.", nameof(problem));
            }

            var validGradeRegexes = new List <string>()
            {
                "AAA",
                "[4-6][a-c][+-]?",
                "B[0-9]",
                "XXX"
            };

            foreach (string grade in problem.Grades)
            {
                if (!validGradeRegexes.Any(regex => Regex.IsMatch(grade, regex)))
                {
                    throw new Exception();
                }
            }
        }
 private static void ValidateProblem(ExistingProblem problem)
 {
     ValidateName(problem);
     ValidateGrades(problem);
     ValiadteHolds(problem);
 }