using adas_core.Application.Exceptions;
using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.MongoModels;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using Serilog;
using System.Text.RegularExpressions;
namespace adas_core.Infrastructure.Repositories;
///
/// Repository implementation for managing entities in MongoDB.
/// Provides CRUD operations and query capabilities specific to light beacons.
///
public class LightBeaconRepository : MongoRepository, ILightBeaconRepository
{
private readonly ApiSettings _apiSettings;
///
/// Initializes a new instance of the class.
///
/// The MongoDB database instance used to access the collection.
/// The application API settings containing configuration values, including the collection name.
public LightBeaconRepository(IMongoDatabase database, IOptions apiSettings) : base(database)
{
_apiSettings = apiSettings.Value;
}
///
/// Gets the name of the MongoDB collection used to store light beacons.
///
/// The collection name retrieved from the API settings.
public override string GetCollectionName()
{
return _apiSettings.LightBeacons;
}
///
/// Retrieves a list of light beacons whose identifiers are contained in the provided list of configuration relay identifiers.
///
/// A list of values representing the relay identifiers to filter by.
/// A containing the matching light beacons. Returns an empty list if no matches are found.
public List GetLightBeaconInList(List configurationRelayList)
{
var filterBuilder = Builders.Filter;
var filter = filterBuilder.And(
filterBuilder.In(r => r.Id, configurationRelayList));
return Collection.Find(filter).ToList();
}
///
/// Asynchronously retrieves a light beacon by its unique identifier.
///
/// The of the relay (light beacon) to retrieve.
///
/// A representing the asynchronous operation.
/// The task result contains the if found; otherwise, .
///
public async Task GetById(ObjectId relayId)
{
try
{
var filter = Builders.Filter.Eq(x => x.Id, relayId);
var result = await Collection.FindAsync(filter, null);
return result.FirstOrDefault();
}
catch (Exception e)
{
Log.Error("Exception trying to get relay by id: {id}. Exception {e}", relayId, e);
return null;
}
}
///
/// Asynchronously retrieves a light beacon by its name.
///
/// The name of the relay (light beacon) to search for. Can be .
///
/// A representing the asynchronous operation.
/// The task result contains the if found; otherwise, .
///
public async Task GetByName(string? requestRelayName)
{
var filterBuilder = Builders.Filter;
var filter = filterBuilder.Eq(r => r.Name, requestRelayName);
return await Collection.Find(filter).FirstOrDefaultAsync();
}
///
/// Asynchronously inserts a new light beacon into the database and returns the inserted entity.
///
/// The instance to insert.
///
/// A representing the asynchronous operation.
/// The task result contains the inserted if successful; otherwise, if the operation fails.
///
public async Task InsertOneAsyncAndReturn(LightBeacon beacon)
{
try
{
await Collection.InsertOneAsync(beacon);
return beacon;
}
catch (Exception ex)
{
Log.Error(ex.Message);
return null;
}
}
///
/// Retrieves a paginated, sorted, and filtered set of light beacons based on the provided pagination filter.
/// Results are sorted ascending by name. When a text filter is provided, a case-insensitive regex match is performed on the name field.
///
/// The containing pagination and filtering criteria.
///
/// An instance that can be used to further refine and execute the query.
///
/// Thrown when the text filter exceeds 100 characters in length.
public IFindFluent GetPaginatedRelays(PaginationFilter filter)
{
var filterBuilder = Builders.Filter;
var sort = Builders.Sort.Ascending("name");
var filters = new List>();
if (filter.FilteredRequest == null)
return CreateFindFluent(filters, sort);
if (!string.IsNullOrWhiteSpace(filter.FilteredRequest.Text))
{
var textFilter = filter.FilteredRequest.Text;
if (textFilter.Length > 100)
throw new BadRequestException("Text filter too long");
var textFilterEscaped = Regex.Escape(textFilter);
filters.Add(
filterBuilder.Regex(
p => p.Name,
new BsonRegularExpression(textFilterEscaped, "i")
)
);
}
return CreateFindFluent(filters, sort);
}
///
/// Searches for light beacons whose name matches the specified text.
///
/// The text to search for within light beacon names.
///
/// A representing the asynchronous operation,
/// containing a list of matching objects.
///
/// This method is not yet implemented.
public Task> GetSearchByName(string textToSearch)
{
throw new NotImplementedException();
}
///
/// Creates an instance by combining the provided filter definitions
/// and applying the specified sort order. If no filters are provided, an empty filter is used.
///
/// A list of to be combined into the query.
/// The defining the sort order of the results.
/// An instance representing the constructed query.
private IFindFluent CreateFindFluent(List> filters, SortDefinition sort)
{
var combinedFilter = filters.Any()
? Builders.Filter.And(filters)
: Builders.Filter.Empty;
return Collection.Find(combinedFilter).Sort(sort);
}
}