/*
     * public async Task ExecuteAsync(AskQuestionCommand command)
     * {
     *  var question = _aggregateRepository.Instantiate(command.QuestionId);
     *
     *  // TODO: Move this into model validation
     *  if (!IsUnique(command.SubjectsTags))
     *      //TODO: Custom exception for this
     *      throw new Exception();
     *
     *  await question.FireEventAsync(new QuestionAskedEvent(command.QuestionId, command.UserId, command.Title, command.Description, command.OccurredAtUtc, DateTime.UtcNow));
     *
     *  foreach (var subjectTag in command.SubjectsTags)
     *      await question.FireEventAsync(new QuestionTaggedEvent(command.QuestionId, subjectTag.SubjectTag, command.OccurredAtUtc, DateTime.UtcNow));
     *
     *  await question.SaveAsync();
     * }
     *
     *
     */

    public async Task ExecuteAsync(AskQuestionCommand command)
    {
        var processTimeUtc = _date.CurrentDateUtc();

        AssertSubjectTagsAreUnique(command.SubjectsTags);

        var question = _aggregateRepository.Instantiate(command.QuestionId);
        await question.FireEventAsync(new QuestionAskedEvent(
                                          command.QuestionId,
                                          command.UserId,
                                          command.Title,
                                          command.Description,
                                          command.OccurredAtUtc,
                                          processTimeUtc));

        await question.SaveAsync();
    }
    public async Task ExecuteAsync(AcceptAnswerCommand command)
    {
        var processedAtUtc = _date.CurrentDateUtc();
        var question       = await _aggregateRepository.RetrieveAsync(command.QuestionId);

        if (question.State.UserId != command.UserId)
        {
            throw new UserPermissionException();
        }

        if (question.State.HasAcceptedAnswer)
        {
            throw new AnswerAlreadyAcceptedException(command.QuestionId);
        }

        if (question.State.Answers.All(x => x.AnswerId != command.AnswerId))
        {
            throw new AnswerNotFoundException();
        }

        await question.FireEventAsync(new AnswerAcceptedEvent(command.QuestionId, command.AnswerId, command.OccurredAtUtc, processedAtUtc));

        await question.SaveAsync();
    }