2023-04-19 12:14:14 +02:00
using System ;
2021-05-13 20:03:07 +02:00
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
2024-04-09 12:53:23 +02:00
using ShareeBike.Model.Bikes ;
using ShareeBike.Model.Connector.Filter ;
using ShareeBike.Model.Services.CopriApi ;
using ShareeBike.Model.Stations ;
using ShareeBike.Model.Stations.StationNS ;
using ShareeBike.Model.Stations.StationNS.Operator ;
using BikeInfo = ShareeBike . Model . Bikes . BikeInfoNS . BC . BikeInfo ;
2021-05-13 20:03:07 +02:00
2024-04-09 12:53:23 +02:00
namespace ShareeBike.Model.Connector
2021-05-13 20:03:07 +02:00
{
2023-04-19 12:14:14 +02:00
/// <summary> Filters connector responses.</summary>
2022-09-06 16:08:19 +02:00
/// <remarks>Former name: Filter</remarks>
public class FilteredConnector : IFilteredConnector
{
/// <summary> Constructs a filter object. </summary>
/// <param name="group">Filter group.</param>
/// <param name="connector">Connector object.</param>
public FilteredConnector (
IEnumerable < string > group ,
IConnector connector )
{
Connector = connector ;
if ( Connector = = null )
{
throw new ArgumentException ( "Can not construct filter object. Connector- and command objects must not be null." ) ;
}
Query = new QueryProvider ( Connector . Query , GroupFilterFactory . Create ( group ) ) ;
}
/// <summary> Inner connector object.</summary>
public IConnector Connector { get ; }
/// <summary> Command object. </summary>
public ICommand Command = > Connector . Command ;
/// <summary> Object to query information. </summary>
public IQuery Query { get ; }
/// <summary> True if connector has access to copri server, false if cached values are used. </summary>
public bool IsConnected = > Connector . IsConnected ;
/// <summary> Object to perform filtered queries.</summary>
private class QueryProvider : IQuery
{
/// <summary> Holds the filter. </summary>
private IGroupFilter Filter { get ; }
2023-04-19 12:14:14 +02:00
/// <summary> Holds the reference to object which performs copri queries.</summary>
2022-09-06 16:08:19 +02:00
private IQuery m_oInnerQuery ;
/// <summary> Constructs a query object.</summary>
/// <param name="innerQuerry"></param>
/// <param name="filter"></param>
public QueryProvider ( IQuery innerQuerry , IGroupFilter filter )
{
m_oInnerQuery = innerQuerry ;
Filter = filter ;
}
/// <summary> Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in. </summary>
2023-11-06 12:23:09 +01:00
/// <param name="operatorUri">Uri of the operator host to get bikes from or null if bikes have to be gotten form primary host.</param>
2023-11-21 15:26:57 +01:00
/// <param name="stationId"> Id of station which is used for filtering bikes. Null if no filtering should be applied.</param>
/// <param name="bikeId"> Id of bike which is used for filtering bikes. Null if no filtering should be applied.</param>
public async Task < Result < BikeCollection > > GetBikesAsync ( Uri operatorUri = null , string stationId = null , string bikeId = null )
2022-09-06 16:08:19 +02:00
{
2023-11-21 15:26:57 +01:00
var result = await m_oInnerQuery . GetBikesAsync ( operatorUri , stationId , bikeId ) ;
2024-04-09 12:53:23 +02:00
if ( bikeId = = null )
{
// Do filter
return new Result < BikeCollection > (
result . Source ,
new BikeCollection ( DoFilter ( result . Response , Filter ) ) ,
result . GeneralData ,
result . Exception ) ;
}
else
{
// Do NOT filter on SelectBikePage = use function from NullFilterConnector: https://dev.azure.com/TeilRad/sharee.bike%20Buchungsplattform/_workitems/edit/904
return new Result < BikeCollection > (
result . Source ,
new BikeCollection ( result . Response . ToDictionary ( x = > x . Id ) ) ,
result . GeneralData ,
result . Exception ) ;
}
2022-09-06 16:08:19 +02:00
}
/// <summary> Gets bikes occupied if a user is logged in. </summary>
public async Task < Result < BikeCollection > > GetBikesOccupiedAsync ( )
{
var result = await m_oInnerQuery . GetBikesOccupiedAsync ( ) ;
return new Result < BikeCollection > (
result . Source ,
new BikeCollection ( result . Response . ToDictionary ( x = > x . Id ) ) ,
result . GeneralData ,
result . Exception ) ;
}
/// <summary> Gets all station applying filter rules. </summary>
/// <returns></returns>
public async Task < Result < StationsAndBikesContainer > > GetBikesAndStationsAsync ( )
{
// Bikes and stations from COPRI or cache
var providerBikesAndStations = await m_oInnerQuery . GetBikesAndStationsAsync ( ) ;
// Do filtering.
2023-05-09 08:47:52 +02:00
var filteredStationsDictionary = new StationDictionary (
providerBikesAndStations . Response . StationsAll . CopriVersion ,
DoFilter ( providerBikesAndStations . Response . StationsAll , Filter ) ) ;
var filteredBikesOccupiedDictionary = new BikeCollection (
DoFilter ( providerBikesAndStations . Response . BikesOccupied , Filter ) ) ;
2022-09-06 16:08:19 +02:00
var filteredBikesAndStations = new Result < StationsAndBikesContainer > (
providerBikesAndStations . Source ,
2023-05-09 08:47:52 +02:00
new StationsAndBikesContainer (
filteredStationsDictionary ,
filteredBikesOccupiedDictionary ) ,
2022-09-06 16:08:19 +02:00
providerBikesAndStations . GeneralData ,
providerBikesAndStations . Exception ) ;
return filteredBikesAndStations ;
}
/// <summary> Filter bikes by group. </summary>
/// <param name="bikes">Bikes to filter.</param>
/// <returns>Filtered bikes.</returns>
2023-05-09 08:47:52 +02:00
private static Dictionary < string , BikeInfo > DoFilter ( BikeCollection bikes , IGroupFilter filter ) = >
bikes
. Where ( x = > filter . DoFilter ( x . Group ) . Count ( ) > 0 )
. ToDictionary ( x = > x . Id ) ;
/// <summary> Filter stations by group and removes bike group collection entries which do not match group filter. </summary>
/// <returns>Matching stations.</returns>
private static Dictionary < string , IStation > DoFilter ( StationDictionary stations , IGroupFilter filter ) = >
stations
. Where ( station = > filter . DoFilter ( station . Group ) . Count ( ) > 0 )
. Select ( station = > new Station (
station . Id ,
station . Group ,
station . Position ,
station . StationName ,
2023-11-06 12:23:09 +01:00
station . OperatorUri ,
2023-05-09 08:47:52 +02:00
station . OperatorData ,
new BikeGroupCol ( station . BikeGroups
. Where ( group = > filter . DoFilter ( new List < string > { group . Group } ) . Count ( ) > 0 ) ) ) as IStation )
. ToDictionary ( x = > x . Id ) ;
2022-09-06 16:08:19 +02:00
}
}
2021-05-13 20:03:07 +02:00
}