using System.Text.Json;
using System.Text.Json.Serialization;
using FinlyticAssets.Models;
using FinlyticAssets.Util;
namespace FinlyticAssets.Services;
///
/// Provides methods for generating and maintaining the indexed asset reference file used for pre-filtering.
///
public interface IAssetsIndexService
{
///
/// Recreates the index file containing basic asset identifiers (ISIN and Name) for all active, valid assets.
///
/// A token to monitor for cancellation requests.
/// A task that represents the asynchronous operation.
public Task ReCreateIndexFileAsync(CancellationToken cancellationToken);
}
///
/// Implements the to maintain local asset index references.
///
public class AssetsIndexService : IAssetsIndexService
{
private readonly ILogger _logger;
private readonly IAssetsDbService _assetsDbService;
///
/// Initializes a new instance of the class.
///
/// The logger for documenting indexing events and errors.
/// The database service to query the assets from.
public AssetsIndexService(ILogger logger, IAssetsDbService assetsDbService)
{
_logger = logger;
_assetsDbService = assetsDbService;
}
///
public async Task ReCreateIndexFileAsync(CancellationToken cancellationToken)
{
try
{
var assets = await _assetsDbService.GetAllValidAssetsAsync();
if (assets == null || !assets.Any())
{
_logger.LogWarning("No valid assets found in the database to index.");
return;
}
var indexAssets = assets.Select(a => new AssetIndex(a.Isin, a.Name)).ToList();
var directoryPath = Volumes.IndexRelativePath;
var filePath = Path.Combine(directoryPath, "index.json");
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096,
useAsync: true))
{
await JsonSerializer.SerializeAsync(fileStream, indexAssets, cancellationToken: cancellationToken);
}
_logger.LogInformation("Successfully recreated asset index file with {Count} entries at {Path}",
indexAssets.Count, filePath);
}
catch (IOException ex)
{
_logger.LogError(ex, "Disk I/O error occurred while writing the asset index file.");
throw;
}
catch (JsonException ex)
{
_logger.LogError(ex, "Failed to serialize the asset index data to JSON.");
throw;
}
catch (Exception ex)
{
_logger.LogError(ex, "An unexpected error occurred while recreating the asset index file.");
throw;
}
}
}