using Mesa_Backlog.Library; using Mesa_Backlog.Library.WorkItems; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Http = System.Net.Http; using IO = System.IO; using WebApi = Microsoft.TeamFoundation.WorkItemTracking.WebApi; namespace Mesa_Backlog.Pages; public class FetchData : PageModel { [BindProperty] public string? JSON { get; set; } [BindProperty] public string? PageName { get; set; } [BindProperty] public string? JsonFileName { get; set; } public bool AreLoaded { init; get; } public List JsonFiles { init; get; } private readonly string _Directory; private readonly AppSettings _AppSettings; private readonly bool _IsEnvironmentDevelopment; private readonly IHostEnvironment _HostEnvironment; private readonly IHttpClientFactory _HttpClientFactory; public List WorkItems { init; get; } private readonly Dictionary _KeyValuePairs; private readonly WebApi.WorkItemTrackingHttpClient _WorkItemTrackingHttpClient; public FetchData(IHostEnvironment hostEnvironment, AppSettings appSettings, IHttpClientFactory httpClientFactory, WebApi.WorkItemTrackingHttpClient workItemTrackingHttpClient, Dictionary keyValuePairs) { JsonFiles = new(); WorkItems = new(); _AppSettings = appSettings; _KeyValuePairs = keyValuePairs; _HostEnvironment = hostEnvironment; _HttpClientFactory = httpClientFactory; _WorkItemTrackingHttpClient = workItemTrackingHttpClient; _IsEnvironmentDevelopment = hostEnvironment.IsDevelopment(); AreLoaded = (from l in keyValuePairs where l.Value is not null select true).Any(); _Directory = Path.Combine(_HostEnvironment.ContentRootPath, ".vscode", "Uploads"); if (!Directory.Exists(_Directory)) _ = Directory.CreateDirectory(_Directory); } private void UpdateKeyValuePairs(FIBacklogMesa[] fIBacklogMesaCollection) { foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection) { if (!_KeyValuePairs.ContainsKey(fIBacklogMesa.Req)) _KeyValuePairs.Add(fIBacklogMesa.Req, null); } } private void SetWorkItems(FIBacklogMesa[] fIBacklogMesaCollection) { UpdateKeyValuePairs(fIBacklogMesaCollection); string project = _AppSettings.Client.Project; string workItemsAddress = $"{_AppSettings.Client.BaseAddress}{_AppSettings.Client.BasePage}{project}/_workItems/edit/"; List workItems = ViewModels.WorkItem.GetWorkItems(_KeyValuePairs, workItemsAddress, fIBacklogMesaCollection); WorkItems.AddRange(workItems); } private IActionResult GetPage(string json) { IActionResult result; FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json); SetWorkItems(fIBacklogMesaCollection); JSON = ExcelReader.GetJson(fIBacklogMesaCollection); string fileName = Path.Combine(_Directory, $"{DateTime.Now.Ticks}.json"); IO.File.WriteAllText(fileName, JSON); result = Page(); return result; } private IActionResult GetPage(List jsonFiles, string jsonFileName) { IActionResult result; string json = IO.File.ReadAllText(jsonFileName); FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json); SetWorkItems(fIBacklogMesaCollection); if (!jsonFiles.Any()) { jsonFiles.AddRange(Directory.GetFiles(_Directory, "*.json")); JsonFiles.AddRange(jsonFiles.OrderByDescending(l => l)); } if (!jsonFiles.Contains(jsonFileName)) { string fileName = Path.Combine(_Directory, $"{DateTime.Now.Ticks}.json"); IO.File.WriteAllText(fileName, JSON); } JSON = json; result = Page(); return result; } private Dictionary GetFlopped() { Dictionary results = new(); foreach (KeyValuePair keyValuePair in _KeyValuePairs) { if (keyValuePair.Value is null) continue; results.Add(keyValuePair.Value.Value, keyValuePair.Key); } return results; } private void MergeBack(Dictionary keyValuePairs) { foreach (KeyValuePair keyValuePair in keyValuePairs) { if (_KeyValuePairs.ContainsKey(keyValuePair.Value)) _KeyValuePairs[keyValuePair.Value] = keyValuePair.Key; else _KeyValuePairs.Add(keyValuePair.Value, keyValuePair.Key); } } private List GetWorkItems() { List results = new(); Root workItem; string query = _AppSettings.Client.Query; using Http.HttpClient httpClient = _HttpClientFactory.CreateClient(nameof(FetchData)); Library.WIQL.WorkItem[] workItems = Library.HttpClient.GetWorkItems(httpClient, _AppSettings.Client.BasePage, _AppSettings.Client.API, query); for (int i = 0; i < workItems.Length; i++) { workItem = Library.HttpClient.GetWorkItem(httpClient, _AppSettings.Client.BasePage, _AppSettings.Client.API, workItems[i].Id); if (workItem is null) break; results.Add(workItem); } return results; } private void CreateNew(string project, Dictionary keyValuePairs, List fIBacklogMesaCollection) { Task workItemTask; foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection.OrderBy(l => int.Parse(l.Req))) { if (string.IsNullOrEmpty(fIBacklogMesa.Title)) continue; workItemTask = WorkItemTrackingHttpClient.CreateWorkItem(_IsEnvironmentDevelopment, _WorkItemTrackingHttpClient, project, fIBacklogMesa); workItemTask.Wait(); if (workItemTask.Result is null) throw new NullReferenceException(nameof(workItemTask.Result)); if (workItemTask.Result?.Id is not null) keyValuePairs.Add(workItemTask.Result.Id.Value, fIBacklogMesa.Req); } } private void PossiblyCreate(FIBacklogMesa[] fIBacklogMesaCollection, Dictionary keyValuePairs) { List collection = new(); foreach (FIBacklogMesa fIBacklogMesa in fIBacklogMesaCollection) { if (string.IsNullOrEmpty(fIBacklogMesa.Title)) continue; if (_KeyValuePairs.ContainsKey(fIBacklogMesa.Req) && _KeyValuePairs[fIBacklogMesa.Req] is not null) continue; collection.Add(fIBacklogMesa); } if (collection.Any() && fIBacklogMesaCollection.Length != collection.Count) CreateNew(_AppSettings.Client.Project, keyValuePairs, collection); } private void Update(string project, List<(int, FIBacklogMesa)> collection) { Task workItemTask; foreach ((int id, FIBacklogMesa fIBacklogMesa) in collection) { if (string.IsNullOrEmpty(fIBacklogMesa.Title)) continue; workItemTask = WorkItemTrackingHttpClient.UpdateWorkItem(_WorkItemTrackingHttpClient, project, id, fIBacklogMesa); workItemTask.Wait(); if (workItemTask.Result is null) throw new NullReferenceException(nameof(workItemTask.Result)); } } private void PossiblyUpdate(FIBacklogMesa[] fIBacklogMesaCollection, List workItems) { int? index; string title; FIBacklogMesa fIBacklogMesa; List<(int, FIBacklogMesa)> collection = new(); foreach (Root workItem in workItems) { index = null; for (int i = 0; i < fIBacklogMesaCollection.Length; i++) { fIBacklogMesa = fIBacklogMesaCollection[i]; if (string.IsNullOrEmpty(fIBacklogMesa.Title)) continue; if (string.IsNullOrEmpty(workItem.Fields.MicrosoftVSTSTCMSystemInfo) || !workItem.Fields.MicrosoftVSTSTCMSystemInfo.Contains(fIBacklogMesa.Req)) continue; index = i; break; } if (index is null) continue; fIBacklogMesa = fIBacklogMesaCollection[index.Value]; title = fIBacklogMesa.Title.Length > 254 ? fIBacklogMesa.Title[..255] : fIBacklogMesa.Title; if (workItem.Fields.SystemTitle != title) collection.Add((workItem.Id, fIBacklogMesa)); else if (workItem.Fields.SystemDescription != fIBacklogMesa.Definition) collection.Add((workItem.Id, fIBacklogMesa)); } if (collection.Any() && fIBacklogMesaCollection.Length != collection.Count) Update(_AppSettings.Client.Project, collection); } private IActionResult GetPage(string json, string pageName) { IActionResult result; FIBacklogMesa[]? fIBacklogMesaCollection = System.Text.Json.JsonSerializer.Deserialize(json); if (fIBacklogMesaCollection is null) throw new NullReferenceException(nameof(fIBacklogMesaCollection)); UpdateKeyValuePairs(fIBacklogMesaCollection); List workItems = GetWorkItems(); if (!workItems.Any()) throw new Exception("Failed to get work items!"); Dictionary keyValuePairs = GetFlopped(); PossiblyCreate(fIBacklogMesaCollection, keyValuePairs); PossiblyUpdate(fIBacklogMesaCollection, workItems); SetWorkItems(fIBacklogMesaCollection); MergeBack(keyValuePairs); result = RedirectToPage($"./{nameof(FetchData)}"); return result; } public IActionResult OnPost() { IActionResult result; WorkItems.Clear(); if (!string.IsNullOrEmpty(JsonFileName)) result = GetPage(JsonFiles, JsonFileName); else if (!string.IsNullOrEmpty(JSON) && string.IsNullOrEmpty(PageName)) result = GetPage(JSON); else if (!string.IsNullOrEmpty(JSON) && !string.IsNullOrEmpty(PageName)) result = GetPage(JSON, PageName); else result = Page(); return result; } private IActionResult SetWorkItemsAndGetPage(string json) { IActionResult result; FIBacklogMesa[] fIBacklogMesaCollection = ExcelReader.GetFIBacklogMesaCollection(json); SetWorkItems(fIBacklogMesaCollection); result = Page(); return result; } public IActionResult OnGet() { IActionResult result; JsonFiles.Clear(); WorkItems.Clear(); string[] jsonFiles = Directory.GetFiles(_Directory, "*.json"); JsonFiles.AddRange(jsonFiles.OrderByDescending(l => l)); if (!string.IsNullOrEmpty(JSON)) result = SetWorkItemsAndGetPage(JSON); else if (!string.IsNullOrEmpty(JsonFileName) && IO.File.Exists(JsonFileName)) { string json = IO.File.ReadAllText(JsonFileName); result = SetWorkItemsAndGetPage(json); } else result = Page(); return result; } }