chore(autocomplete): documentation

This commit is contained in:
2026-03-11 14:38:12 +01:00
parent a0de93f98c
commit 0e8c9fc691

View File

@@ -10,6 +10,14 @@ using CarManagerV3.Classes;
namespace CarManagerV3.Util namespace CarManagerV3.Util
{ {
/// <summary>
/// Provides car manufacturer and model autocompletion data for the application.
/// Manages fetching, caching, and retrieval of car brand and model information from remote sources and local storage.
/// </summary>
/// <remarks>
/// This class maintains a static list of car manufacturers and their models, supports fetching updated data from remote URLs,
/// and caches the data locally for offline use. It implements retry logic to prevent excessive network requests.
/// </remarks>
internal class CarCompletions internal class CarCompletions
{ {
/// <summary> /// <summary>
@@ -21,10 +29,28 @@ namespace CarManagerV3.Util
"https://static.clsw.app/carmgm/merged-cars.json" "https://static.clsw.app/carmgm/merged-cars.json"
}; };
/// <summary>
/// The filename for the cached car completion data in the user's data directory.
/// </summary>
private static readonly string carCompletionDataFileName = "car_data.json"; private static readonly string carCompletionDataFileName = "car_data.json";
/// <summary>
/// The timestamp of the last fetch attempt for car completion data.
/// Used to implement retry throttling to prevent excessive network requests.
/// </summary>
private static DateTime lastFetchAttempt = Properties.Settings.Default.LastFetchedAutoCompletions; private static DateTime lastFetchAttempt = Properties.Settings.Default.LastFetchedAutoCompletions;
/// <summary>
/// The minimum time interval that must elapse between fetch attempts.
/// Prevents excessive retry attempts when the remote source is unavailable.
/// </summary>
private static readonly TimeSpan fetchRetryInterval = Properties.Settings.Default.FetchAutoCompletionsInterval; // Minimum interval between fetch attempts private static readonly TimeSpan fetchRetryInterval = Properties.Settings.Default.FetchAutoCompletionsInterval; // Minimum interval between fetch attempts
/// <summary>
/// Gets the full file path for the car completion data file.
/// Ensures that the user data directory exists before returning the path.
/// </summary>
/// <returns>The full file path to the car completion data file in the user's data directory.</returns>
private static string getCarCompletionDataFilePath() private static string getCarCompletionDataFilePath()
{ {
var userDataDir = Properties.Settings.Default.DataLocation; var userDataDir = Properties.Settings.Default.DataLocation;
@@ -32,6 +58,10 @@ namespace CarManagerV3.Util
return Path.Combine(userDataDir, carCompletionDataFileName); return Path.Combine(userDataDir, carCompletionDataFileName);
} }
/// <summary>
/// The static list of car manufacturers and their available models.
/// This list serves as the default data and is updated when fetching from remote sources or local cache.
/// </summary>
public static List<CarManufacturer> carBrands = new List<CarManufacturer> public static List<CarManufacturer> carBrands = new List<CarManufacturer>
{ {
new CarManufacturer("Toyota") { Models = new List<string> { "Camry", "Corolla", "RAV4" } }, new CarManufacturer("Toyota") { Models = new List<string> { "Camry", "Corolla", "RAV4" } },
@@ -48,22 +78,45 @@ namespace CarManagerV3.Util
new CarManufacturer("Skoda") { Models = new List<string> { "Octavia", "Fabia", "Kodiaq" } }, new CarManufacturer("Skoda") { Models = new List<string> { "Octavia", "Fabia", "Kodiaq" } },
}; };
/// <summary>
/// Gets the full list of car brands.
/// </summary>
/// <returns>A list of strings containing all available car manufacturer names.</returns>
public static List<string> GetCarBrands() public static List<string> GetCarBrands()
{ {
return carBrands.Select(c => c.Name).ToList(); return carBrands.Select(c => c.Name).ToList();
} }
/// <summary>
/// Retrieves the list of car models for a specified brand.
/// The search is case-insensitive.
/// </summary>
/// <param name="brand">The name of the car brand to search for.</param>
/// <returns>A list of car models for the specified brand, or an empty list if the brand is not found.</returns>
public static List<string> GetCarModels(string brand) public static List<string> GetCarModels(string brand)
{ {
var manufacturer = carBrands.FirstOrDefault(c => c.Name.Equals(brand, StringComparison.OrdinalIgnoreCase)); var manufacturer = carBrands.FirstOrDefault(c => c.Name.Equals(brand, StringComparison.OrdinalIgnoreCase));
return manufacturer != null ? manufacturer.Models : new List<string>(); return manufacturer != null ? manufacturer.Models : new List<string>();
} }
/// <summary>
/// A predefined list of common car colors for autocompletion purposes.
/// Provides standard color options that are frequently used in vehicle descriptions.
/// </summary>
public static List<string> CommonColors = new List<string> public static List<string> CommonColors = new List<string>
{ {
"Black", "White", "Gray", "Silver", "Red", "Blue", "Green", "Yellow", "Brown", "Orange" "Black", "White", "Gray", "Silver", "Red", "Blue", "Green", "Yellow", "Brown", "Orange"
}; };
/// <summary>
/// Reads car completion data from an embedded resource file.
/// This method is intended to populate the carBrands list from a JSON resource embedded in the project.
/// </summary>
/// <remarks>
/// The expected resource format is a JSON object where keys are car brand names and values are lists of model names.
/// Resource name: CarCompleteData (JSON file format).
/// Currently not implemented.
/// </remarks>
public static void ReadFromResourceFile() public static void ReadFromResourceFile()
{ {
// Read the json file from the projects resources and populate the carBrands list // Read the json file from the projects resources and populate the carBrands list
@@ -77,7 +130,12 @@ namespace CarManagerV3.Util
/// <summary> /// <summary>
/// Fetches the car data from urls asynchronous and saves it in the users data directory for offline use. /// Fetches the car data from urls asynchronous and saves it in the users data directory for offline use.
/// </summary> /// </summary>
/// <returns></returns> /// <returns>A task representing the asynchronous operation.</returns>
/// <remarks>
/// This method implements retry throttling using the <see cref="fetchRetryInterval"/> to prevent excessive network requests.
/// It attempts to fetch data from each URL in <see cref="carDataFileUrls"/> in order until successful or all URLs are exhausted.
/// The fetched data is saved to the local file system for offline access.
/// </remarks>
public static async Task FetchCarCompletionDataFromUrlsAsync() public static async Task FetchCarCompletionDataFromUrlsAsync()
{ {
if(DateTime.Now - lastFetchAttempt < fetchRetryInterval) if(DateTime.Now - lastFetchAttempt < fetchRetryInterval)
@@ -97,11 +155,10 @@ namespace CarManagerV3.Util
var response = await httpClient.GetAsync(url); var response = await httpClient.GetAsync(url);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var jsonData = await response.Content.ReadAsStringAsync(); var jsonData = await response.Content.ReadAsStringAsync();
// Save the json data to a file in the user's data directory for offline use // Saves the json data to a file in the user's data directory for offline use
var filePath = getCarCompletionDataFilePath(); var filePath = getCarCompletionDataFilePath();
await File.WriteAllTextAsync(filePath, jsonData); await File.WriteAllTextAsync(filePath, jsonData);
System.Diagnostics.Debug.WriteLine($"Successfully fetched car data from {url} and saved to {filePath}"); System.Diagnostics.Debug.WriteLine($"Successfully fetched car data from {url} and saved to {filePath}");
// Optionally, you can also parse the json data and populate the carBrands list here
break; // Exit the loop if data is successfully fetched break; // Exit the loop if data is successfully fetched
} }
catch (Exception ex) catch (Exception ex)
@@ -115,14 +172,29 @@ namespace CarManagerV3.Util
/// <summary> /// <summary>
/// Fetches the car data from urls and saves it in the users data directory for offline use. /// Fetches the car data from urls and saves it in the users data directory for offline use.
/// This is a synchronous wrapper that blocks until the asynchronous fetch operation completes.
/// </summary> /// </summary>
/// <returns></returns> /// <returns>A task representing the synchronous operation.</returns>
/// <remarks>
/// This method wraps <see cref="FetchCarCompletionDataFromUrlsAsync"/> and runs it synchronously.
/// Consider using the async version directly when possible to avoid blocking the thread.
/// </remarks>
public static Task FetchCarCompletionDataFromUrls() public static Task FetchCarCompletionDataFromUrls()
{ {
// Run synchronously // Run synchronously
return Task.Run(() => FetchCarCompletionDataFromUrlsAsync().Wait()); return Task.Run(() => FetchCarCompletionDataFromUrlsAsync().Wait());
} }
/// <summary>
/// Loads car manufacturer data from the locally cached file.
/// Optionally fetches updated data from remote sources before loading from file.
/// </summary>
/// <param name="skipOnlineUpdate">If true, skips fetching data from remote sources and only reads from the local cache. Default is false.</param>
/// <returns>A list of <see cref="CarManufacturer"/> objects populated from the cached file, or an empty list if the file doesn't exist or an error occurs.</returns>
/// <remarks>
/// The expected file format is a JSON object where keys are car brand names and values are lists of model names.
/// If the file doesn't exist or cannot be read, an error message is logged and an empty list is returned.
/// </remarks>
public static List<CarManufacturer> GetFromFile(bool skipOnlineUpdate = false) public static List<CarManufacturer> GetFromFile(bool skipOnlineUpdate = false)
{ {
if (!skipOnlineUpdate) FetchCarCompletionDataFromUrls(); if (!skipOnlineUpdate) FetchCarCompletionDataFromUrls();
@@ -151,6 +223,15 @@ namespace CarManagerV3.Util
return new List<CarManufacturer>(); return new List<CarManufacturer>();
} }
/// <summary>
/// Updates the static <see cref="carBrands"/> list with data from the local cache file.
/// Only updates the list if the cached file contains valid data.
/// </summary>
/// <param name="skipOnlineUpdate">If true, skips fetching data from remote sources before updating. Default is false.</param>
/// <remarks>
/// This method calls <see cref="GetFromFile"/> and updates <see cref="carBrands"/> only if the returned list is not empty.
/// If no data is retrieved, the existing <see cref="carBrands"/> list remains unchanged.
/// </remarks>
public static void UpdateCarCompletionData(bool skipOnlineUpdate = false) public static void UpdateCarCompletionData(bool skipOnlineUpdate = false)
{ {
var updatedCarBrands = GetFromFile(skipOnlineUpdate); var updatedCarBrands = GetFromFile(skipOnlineUpdate);
@@ -160,6 +241,15 @@ namespace CarManagerV3.Util
} }
} }
/// <summary>
/// Asynchronously updates the car completion data by fetching from remote sources and updating the local cache.
/// This is the recommended method for refreshing car data in the application.
/// </summary>
/// <returns>A task representing the asynchronous update operation.</returns>
/// <remarks>
/// This method first attempts to fetch updated data from remote URLs using <see cref="FetchCarCompletionDataFromUrlsAsync"/>,
/// then updates the static <see cref="carBrands"/> list from the local cache using <see cref="UpdateCarCompletionData"/>.
/// </remarks>
public static async Task UpdateCarCompletionDataAsync() public static async Task UpdateCarCompletionDataAsync()
{ {
await FetchCarCompletionDataFromUrlsAsync(); await FetchCarCompletionDataFromUrlsAsync();