public async Task <JsonResult> GetCharacterList([FromServices] IReadonlyCharacterRepository characterRepository)
        {
            if (characterRepository == null)
            {
                throw new ArgumentNullException(nameof(characterRepository));
            }

            //The account id should be in the JWT/claim sent. It's required to load the characters from the database
            //that are associated with the account.
            int accountId = HaloLiveUserManager.GetUserIdInt(User);

            //We don't load additional uneeded information. The Ids are enough for the client to load their names, profiles and appearance if required.
            int[] characterIds = (await characterRepository.LoadAssociatedCharacterIds(accountId)).ToArray();
            characterIds = characterIds ?? Enumerable.Empty <int>().ToArray();

            //We don't need to do anything fancy. The ID of the characters is TRULY enough for the client to then request and piece together all the other missing content
            return(Json(new CharacterListResponse(characterIds)));
        }
        public async Task <IActionResult> NameQuery(int id, [FromServices] IReadonlyCharacterRepository characterRepository)
        {
            if (characterRepository == null)
            {
                throw new ArgumentNullException(nameof(characterRepository));
            }

            if (id < 0)
            {
                return(StatusCode(422));                //Unprocessable Entity
            }
            string name = await characterRepository.GetCharacterName(id);

            //We should assume it's unknown. There could be other issues but the user does not need to know this.
            if (string.IsNullOrWhiteSpace(name))
            {
                return(Json(new NameQueryResponse(NameQueryResponseCode.UnknownUserId)));
            }

            return(Json(new NameQueryResponse(name)));
        }
        public async Task <JsonResult> CheckCharacterNameAvailability([FromBody] CharacterNameValidationRequest request, [FromServices] IReadonlyCharacterRepository characterRepository)
        {
            if (!ModelState.IsValid)
            {
                return(GenerateValidationResponse(CharacterNameValidationResponseCode.GeneralServerError));
            }

            if (String.IsNullOrWhiteSpace(request.CharacterName))
            {
                return(GenerateValidationResponse(CharacterNameValidationResponseCode.NameContainsInvalidCharacters));
            }

            if (!CharacterNameValidator.isNameValidLength(request.CharacterName))
            {
                return(GenerateValidationResponse(CharacterNameValidationResponseCode.NameIsInvalidLength));
            }

            if (!CharacterNameValidator.isNameValidCharacters(request.CharacterName))
            {
                return(GenerateValidationResponse(CharacterNameValidationResponseCode.NameContainsInvalidCharacters));
            }

            bool isNameTaken;

            //We wrap this in a try because something could be broken db/network wise. We just want to tell the user that something broke instead of
            //breaking their client with malformed responses too
            try
            {
                //At this point the name looks valid but we still don't know if we have another character with that name.
                isNameTaken = await characterRepository.DoesNameExist(request.CharacterName);
            }
            catch (Exception e)
            {
                //TODO: Logging
                return(GenerateValidationResponse(CharacterNameValidationResponseCode.GeneralServerError));
            }

            return(!isNameTaken?GenerateValidationResponse(CharacterNameValidationResponseCode.Success)
                       : GenerateValidationResponse(CharacterNameValidationResponseCode.NameAlreadyTaken));
        }