public async Task <IUserDetails> RequestAPIKey(string applicationReference, CancellationToken cancellationToken)
        {
            // TODO: refactor this mess
            var uuid = Guid.NewGuid().ToString();

            var initialPayload = _jSONService.Serialize(new { id = uuid, protocol = 2, token = "" });

            var responseData = new { success = false, data = new { api_key = "", connection_token = "" }, error = "" };

            using var socket = new ClientWebSocket();

            // Configure the socket
            socket.Options.KeepAliveInterval = TimeSpan.FromSeconds(45);

            // Connecting to the server
            await socket.ConnectAsync(new Uri(NexusModsSSOServer), cancellationToken);

            // Sending first request to get a connection_token, the token with implementation is not needed.
            await socket.SendAsync(new ArraySegment <byte>(Encoding.UTF8.GetBytes(initialPayload)), WebSocketMessageType.Text, true, cancellationToken);

            // Receiving the connection_token.
            var responseBuffer = new ArraySegment <byte>(new byte[512]);
            await socket.ReceiveAsync(responseBuffer, cancellationToken);

            // Store the connection_token.
            responseData = _jSONService.Deserialize(Encoding.UTF8.GetString(responseBuffer), responseData);

            if (!responseData.success)
            {
                throw new APIException(responseData.error, HttpStatusCode.ServiceUnavailable);
            }

            // Open the browser to prompt the user to authorize the request via the nexus mods website (SSO Service).
            OpenBrowser(@"https://www.nexusmods.com/sso?id=" + uuid + "&application=" + applicationReference);

            // Receiving the API key.
            responseBuffer = new ArraySegment <byte>(new byte[512]);
            await socket.ReceiveAsync(responseBuffer, cancellationToken);

            // Store the API Key.
            responseData = _jSONService.Deserialize(Encoding.UTF8.GetString(responseBuffer), responseData);

            if (!responseData.success)
            {
                throw new APIException(responseData.error, HttpStatusCode.ServiceUnavailable);
            }

            // Checking to make sure the API Key was received, otherwise throw an exception.
            if (string.IsNullOrWhiteSpace(responseData.data.api_key))
            {
                throw new APIException(
                          $"Unable to receive the API Key,{Environment.NewLine}",
                          HttpStatusCode.ServiceUnavailable);
            }

            var userDetails = await ValidateAPIKey(responseData.data.api_key, cancellationToken);

            return(userDetails);
        }
        private IEnumerable <IGameDetails> GetEmbeddedGames()
        {
            // use the Embedded resource file "games.json"
            var resourceName = Assembly.GetExecutingAssembly()
                               .GetManifestResourceNames()
                               .First(r => r.EndsWith("games.json"));

            using var stream = Assembly.GetExecutingAssembly()
                               .GetManifestResourceStream(resourceName);

            using var reader = new StreamReader(stream ?? throw new InvalidOperationException("Couldn't find the embedded resource file games.json"));
            var json  = reader.ReadToEnd();
            var games = _jsonService.Deserialize <GameDetails[]>(json);

            return(games);
        }