using System; using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Net.Mime; using System.Security.Authentication; using System.Threading.Tasks; using FarmmapsApi.Models; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using static IdentityModel.OidcConstants; namespace FarmmapsApi.Services { public class FarmmapsApiService { private readonly HttpClient _httpClient; private readonly OpenIdConnectService _openIdConnectService; private readonly Configuration _configuration; public FarmmapsApiService(HttpClient httpClient, OpenIdConnectService openIdConnectService, Configuration configuration) { _httpClient = httpClient; _openIdConnectService = openIdConnectService; _configuration = configuration; _httpClient.BaseAddress = new Uri(configuration.Endpoint); _httpClient.DefaultRequestHeaders.Add("Accept", MediaTypeNames.Application.Json); } public async Task AuthenticateAsync() { if (_httpClient.DefaultRequestHeaders.Authorization != null && _httpClient.DefaultRequestHeaders.Authorization.Scheme != AuthenticationSchemes.AuthorizationHeaderBearer) throw new AuthenticationException("Already seems to be authenticated"); var disco = await _openIdConnectService.GetDiscoveryDocumentAsync(); var token = await _openIdConnectService.GetTokenClientCredentialsAsync(disco.TokenEndpoint, _configuration.ClientId, _configuration.ClientSecret); if (token.IsError) throw new AuthenticationException(token.Error); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.AuthorizationHeaderBearer, token.AccessToken); } public async Task GetCurrentUserCodeAsync() { var response = await _httpClient.GetAsync(ResourceEndpoints.CURRENTUSER_RESOURCE); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); var json = JsonConvert.DeserializeObject(jsonString); return json["code"].Value(); } public async Task> GetCurrentUserRootsAsync() { var response = await _httpClient.GetAsync(ResourceEndpoints.MYROOTS_RESOURCE); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject>(jsonString); } public async Task GetItemAsync(string itemCode) { var resourceUri = string.Format(ResourceEndpoints.ITEMS_RESOURCE, itemCode); var response = await _httpClient.GetAsync(resourceUri); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(jsonString); } public async Task> GetItemChildrenAsync(string itemCode) { var resourceUri = string.Format(ResourceEndpoints.ITEMS_CHILDREN_RESOURCE, itemCode); var response = await _httpClient.GetAsync(resourceUri); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject>(jsonString); } public async Task CreateItemAsync(ItemRequest itemRequest) { var jsonString = JsonConvert.SerializeObject(itemRequest); var response = await _httpClient.PostAsync(ResourceEndpoints.ITEMS_CREATE_RESOURCE, new StringContent(jsonString)); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonStringResponse = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(jsonStringResponse); } public async Task DeleteItemAsync(string itemCode) { var resourceUri = string.Format(ResourceEndpoints.ITEMS_RESOURCE, itemCode); var response = await _httpClient.DeleteAsync(resourceUri); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); } public async Task DeleteItemsAsync(IList itemCodes) { var jsonString = JsonConvert.SerializeObject(itemCodes); var content = new StringContent(jsonString); var response = await _httpClient.PostAsync(ResourceEndpoints.ITEMS_DELETE_RESOURCE, content); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); } public async Task DownloadItemAsync(string itemCode, string filePath) { var resourceUri = string.Format(ResourceEndpoints.ITEMS_DOWNLOAD_RESOURCE, itemCode); var response = await _httpClient.GetAsync(resourceUri, HttpCompletionOption.ResponseHeadersRead); if(response.IsSuccessStatusCode) { await using Stream streamToReadFrom = await response.Content.ReadAsStreamAsync(); await using Stream streamToWriteTo = File.Open(filePath, FileMode.Create); await streamToReadFrom.CopyToAsync(streamToWriteTo); } else { throw new FileNotFoundException(response.ReasonPhrase); } } public async Task QueueTaskAsync(string itemCode, TaskRequest taskRequest) { var resourceUri = string.Format(ResourceEndpoints.ITEMTASK_REQUEST_RESOURCE, itemCode); var jsonString = JsonConvert.SerializeObject(taskRequest); var response = await _httpClient.PostAsync(resourceUri, new StringContent(jsonString)); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonStringResponse = await response.Content.ReadAsStringAsync(); var json = JsonConvert.DeserializeObject(jsonStringResponse); return json["code"].Value(); } public async Task> GetTasksStatusAsync(string itemCode) { var resourceUri = string.Format(ResourceEndpoints.ITEMTASKS_RESOURCE, itemCode); var response = await _httpClient.GetAsync(resourceUri); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject>(jsonString); } public async Task GetTaskStatusAsync(string itemCode, string itemTaskCode) { var resourceUri = string.Format(ResourceEndpoints.ITEMTASK_RESOURCE, itemCode, itemTaskCode); var response = await _httpClient.GetAsync(resourceUri); if (!response.IsSuccessStatusCode) throw new Exception(response.ReasonPhrase); var jsonString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(jsonString); } } }