/// <summary>
 /// Gets all Custom Devices
 /// </summary>
 /// <param name="accessToken">The OAuth2 access token</param>
 /// <param name="resultHandler">The result handler</param>
 /// <returns></returns>
 public static async Task <IActionResult> GetCustomDevicesAsync(string accessToken, ResultHandler <List <CustomDevice> > resultHandler)
 {
     using (var restApi = new SmartMeApiClient(accessToken))
     {
         return(await restApi.GetAsync <List <CustomDevice> >("CustomDevice", resultHandler));
     }
 }
        /// <summary>
        /// Sends a POST request to the specified relative url with the provided content and returns the added resource.
        /// The result handler executes the success and error delegate based on the response of the POST request.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeUrl"></param>
        /// <param name="content"></param>
        /// <param name="resultHandler"></param>
        /// <returns></returns>
        public async Task <IActionResult> PostAddAsync <T>(string relativeUrl, T content, ResultHandler <T> resultHandler)
        {
            string jsonContent = JsonConvert.SerializeObject(content);
            var    httpContent = new StringContent(jsonContent, Encoding.UTF8, "application/json");
            var    response    = await client.PostAsync(relativeUrl, httpContent);

            if (response.IsSuccessStatusCode)
            {
                string responseContent = await response.Content.ReadAsStringAsync();

                var result = JsonConvert.DeserializeObject <T>(responseContent);
                return(resultHandler.OnSuccess?.Invoke(result));
            }
            else
            {
                return(await HandleUnsuccessfulHttpResponse(response, resultHandler));
            }
        }
        /// <summary>
        /// Execute the error delegate of the result handler in case of unsuccessful http responses.
        /// </summary>
        /// <param name="response"></param>
        /// <param name="resultHandler"></param>
        private async Task <IActionResult> HandleUnsuccessfulHttpResponse <T>(HttpResponseMessage response, ResultHandler <T> resultHandler)
        {
            string errorMessage = await response.Content.ReadAsStringAsync();

            if (errorMessage == null)
            {
                errorMessage = "";
            }

            ErrorType errorType = ErrorType.Generic;

            switch (response.StatusCode)
            {
            case HttpStatusCode.Unauthorized:
                errorType = ErrorType.Unauthorized;
                break;

            case HttpStatusCode.NotFound:
            case HttpStatusCode.BadRequest:
                errorType = ErrorType.InvalidArgument;
                break;

            case HttpStatusCode.InternalServerError:
                errorType = ErrorType.InvalidOperation;
                break;

            case HttpStatusCode.RequestTimeout:
                errorType = ErrorType.Timeout;
                break;
            }

            return(resultHandler.OnError?.Invoke(errorType, errorMessage));
        }
        /// <summary>
        /// Sends a GET request to the specified relative url with the provided parameters.
        /// The result handler executes the success and error delegate based on the response of the POST request.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="relativeUrl"></param>
        /// <param name="parameters"></param>
        /// <param name="resultHandler"></param>
        /// <returns></returns>
        public async Task <IActionResult> GetAsync <T>(string relativeUrl, Dictionary <string, object> parameters, ResultHandler <T> resultHandler)
        {
            // Build full url including query parameters
            var query = HttpUtility.ParseQueryString(string.Empty);

            foreach (var parameter in parameters.Keys)
            {
                query[parameter] = parameters[parameter].ToString();
            }

            var builder = new UriBuilder(baseUrl + relativeUrl);

            builder.Query = query.ToString();

            var response = await client.GetAsync(builder.ToString());

            if (response.IsSuccessStatusCode)
            {
                string content = await response.Content.ReadAsStringAsync();

                var result = JsonConvert.DeserializeObject <T>(content);
                return(resultHandler.OnSuccess?.Invoke(result));
            }
            else
            {
                return(await HandleUnsuccessfulHttpResponse(response, resultHandler));
            }
        }