/**
  *
  * Validates Create Run request
  *
  * @param Request $r
  * @throws ApiException
  * @throws InvalidDatabaseOperationException
  * @throws NotAllowedToSubmitException
  * @throws InvalidParameterException
  * @throws ForbiddenAccessException
  */
 private static function validateCreateRequest(Request $r)
 {
     // https://github.com/omegaup/omegaup/issues/739
     if ($r['current_user']->username == 'omi') {
         throw new ForbiddenAccessException();
     }
     $allowedLanguages = array('kp', 'kj', 'c', 'cpp', 'cpp11', 'java', 'py', 'rb', 'pl', 'cs', 'pas', 'cat', 'hs');
     try {
         Validators::isStringNonEmpty($r['problem_alias'], 'problem_alias');
         // Check that problem exists
         $r['problem'] = ProblemsDAO::getByAlias($r['problem_alias']);
         if ($r['problem']->deprecated) {
             throw new PreconditionFailedException('problemDeprecated');
         }
         $allowedLanguages = array_intersect($allowedLanguages, explode(',', $r['problem']->languages));
         Validators::isInEnum($r['language'], 'language', $allowedLanguages);
         Validators::isStringNonEmpty($r['source'], 'source');
         // Check for practice or public problem, there is no contest info in this scenario
         if ($r['contest_alias'] == '') {
             if (Authorization::IsProblemAdmin($r['current_user_id'], $r['problem']) || time() > ProblemsDAO::getPracticeDeadline($r['problem']->getProblemId()) || $r['problem']->getPublic() == true) {
                 if (!RunsDAO::IsRunInsideSubmissionGap(null, $r['problem']->getProblemId(), $r['current_user_id']) && !Authorization::IsSystemAdmin($r['current_user_id'])) {
                     throw new NotAllowedToSubmitException('runWaitGap');
                 }
                 self::$practice = true;
                 return;
             } else {
                 throw new NotAllowedToSubmitException('problemIsNotPublic');
             }
         }
         // Validate contest
         Validators::isStringNonEmpty($r['contest_alias'], 'contest_alias');
         $r['contest'] = ContestsDAO::getByAlias($r['contest_alias']);
         if ($r['contest'] == null) {
             throw new InvalidParameterException('parameterNotFound', 'contest_alias');
         }
         if ($r['contest']->languages !== null) {
             $allowedLanguages = array_intersect($allowedLanguages, explode(',', $r['contest']->languages));
             Validators::isInEnum($r['language'], 'language', $allowedLanguages);
         }
         // Validate that the combination contest_id problem_id is valid
         if (!ContestProblemsDAO::getByPK($r['contest']->getContestId(), $r['problem']->getProblemId())) {
             throw new InvalidParameterException('parameterNotFound', 'problem_alias');
         }
         // Contest admins can skip following checks
         if (!Authorization::IsContestAdmin($r['current_user_id'], $r['contest'])) {
             // Before submit something, contestant had to open the problem/contest
             if (!ContestsUsersDAO::getByPK($r['current_user_id'], $r['contest']->getContestId())) {
                 throw new NotAllowedToSubmitException('runNotEvenOpened');
             }
             // Validate that the run is timely inside contest
             if (!ContestsDAO::isInsideContest($r['contest'], $r['current_user_id'])) {
                 throw new NotAllowedToSubmitException('runNotInsideContest');
             }
             // Validate if contest is private then the user should be registered
             if ($r['contest']->getPublic() == 0 && is_null(ContestsUsersDAO::getByPK($r['current_user_id'], $r['contest']->getContestId()))) {
                 throw new NotAllowedToSubmitException('runNotRegistered');
             }
             // Validate if the user is allowed to submit given the submissions_gap
             if (!RunsDAO::IsRunInsideSubmissionGap($r['contest']->getContestId(), $r['problem']->getProblemId(), $r['current_user_id'])) {
                 throw new NotAllowedToSubmitException('runWaitGap');
             }
         }
     } catch (ApiException $apiException) {
         // Propagate ApiException
         throw $apiException;
     } catch (Exception $e) {
         // Operation failed in the data layer
         throw new InvalidDatabaseOperationException($e);
     }
 }