﻿// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
// 
//   http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Org.Apache.REEF.Tang.Annotations;
using Org.Apache.REEF.Utilities.AsyncUtils;

namespace Org.Apache.REEF.Client.YARN.RestClient
{
    /// <summary>
    /// Implementation of RestClient which uses HTTPClient to 
    /// make REST requests and handles errors
    /// </summary>
    internal class RestClient : IRestClient
    {
        private readonly IDeserializer _deserializer;
        private readonly IHttpClient _httpClient;

        [Inject]
        private RestClient(IDeserializer deserializer, IHttpClient httpClient)
        {
            _httpClient = httpClient;
            _deserializer = deserializer;
        }

        /// <summary>
        /// Execute request where no response object is expected
        /// </summary>
        public async Task<RestResponse<VoidResult>> ExecuteRequestAsync(
            RestRequest request,
            Uri requestBaseUri,
            CancellationToken cancellationToken)
        {
            var httpResponseMessage = await GetHttpResponseAsync(request, requestBaseUri, cancellationToken);
            Exception exception = null;
            if (!httpResponseMessage.IsSuccessStatusCode)
            {
                exception =
                    new HttpRequestException(string.Format("HTTP call failed with status [{0}] and content [{1}]",
                        httpResponseMessage.StatusCode,
                        await GetContentStringFromHttpResponseMessage(httpResponseMessage)));
            }

            return new RestResponse<VoidResult>
            {
                Data = new VoidResult(),
                Exception = exception,
                StatusCode = httpResponseMessage.StatusCode
            };
        }

        /// <summary>
        /// Execute request where the response is expected to be type T
        /// </summary>
        public async Task<RestResponse<T>> ExecuteRequestAsync<T>(
            RestRequest request,
            Uri requestBaseUri,
            CancellationToken cancellationToken)
        {
            var httpResponseMessage = await GetHttpResponseAsync(request, requestBaseUri, cancellationToken);
            string contentString = await GetContentStringFromHttpResponseMessage(httpResponseMessage);
            Exception exception = null;
            T returnObj = default(T);

            if (!httpResponseMessage.IsSuccessStatusCode)
            {
                exception =
                    new HttpRequestException(string.Format("HTTP call failed with status [{0}] and content [{1}]",
                        httpResponseMessage.StatusCode,
                        contentString));
            }
            else
            {
                returnObj = _deserializer.Deserialize<T>(contentString,
                    request.RootElement);
            }
            return new RestResponse<T>
            {
                Content = contentString,
                Data = returnObj,
                StatusCode = httpResponseMessage.StatusCode,
                Exception = exception
            };
        }

        private async Task<HttpResponseMessage> GetHttpResponseAsync(
            RestRequest request,
            Uri requestBaseUri,
            CancellationToken cancellationToken)
        {
            HttpResponseMessage httpResponseMessage;
            var requestResource = requestBaseUri + request.Resource;
            switch (request.Method)
            {
                case Method.GET:
                    httpResponseMessage = await _httpClient.GetAsync(
                        requestResource,
                        cancellationToken);
                    break;
                case Method.PUT:
                    httpResponseMessage = await _httpClient.PutAsync(
                        requestResource,
                        request.Content,
                        cancellationToken);
                    break;
                case Method.POST:
                    httpResponseMessage = await _httpClient.PostAsync(
                        requestResource,
                        request.Content,
                        cancellationToken);
                    break;
                default:
                    throw new InvalidOperationException(string.Format("Unknown method type {0}", request.Method));
            }

            return httpResponseMessage;
        }

        private static async Task<string> GetContentStringFromHttpResponseMessage(HttpResponseMessage response)
        {
            return response.Content == null ? string.Empty : await response.Content.ReadAsStringAsync();
        }
    }
}