using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TINK.Model.Bikes;
using TINK.Model.Services.CopriApi;
using TINK.Model.Stations;
using TINK.Model.Stations.StationNS;
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector
{
/// Filters connector responses.
public class NullFilterConnector : IFilteredConnector
{
/// Constructs a filter object.
/// Filter group.
/// Connector object.
public NullFilterConnector(
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);
}
/// Inner connector object.
public IConnector Connector { get; }
/// Command object.
public ICommand Command => Connector.Command;
/// Object to query information.
public IQuery Query { get; }
/// True if connector has access to copri server, false if cached values are used.
public bool IsConnected => Connector.IsConnected;
/// Object to perform filtered queries.
private class QueryProvider : IQuery
{
/// Holds the reference to object which performs copri queries.
private IQuery m_oInnerQuery;
/// Constructs a query object.
///
///
public QueryProvider(IQuery p_oInnerQuery)
{
m_oInnerQuery = p_oInnerQuery;
}
/// Gets bikes either bikes available if no user is logged in or bikes available and bikes occupied if a user is logged in.
public async Task> GetBikesAsync()
{
var result = await m_oInnerQuery.GetBikesAsync();
return new Result(
result.Source,
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
result.GeneralData,
result.Exception);
}
/// Gets bikes occupied if a user is logged in.
public async Task> GetBikesOccupiedAsync()
{
var result = await m_oInnerQuery.GetBikesOccupiedAsync();
return new Result(
result.Source,
new BikeCollection(result.Response.ToDictionary(x => x.Id)),
result.GeneralData,
result.Exception);
}
/// Gets all station applying filter rules.
///
public async Task> GetBikesAndStationsAsync()
{
var result = await m_oInnerQuery.GetBikesAndStationsAsync();
return new Result(
result.Source,
new StationsAndBikesContainer(
new StationDictionary(
result.Response.StationsAll.CopriVersion,
result.Response.StationsAll.ToDictionary(x => x.Id)),
new BikeCollection(
result.Response.BikesOccupied?.ToDictionary(x => x.Id) ?? new Dictionary())),
result.GeneralData,
result.Exception);
}
/// Filter bikes by group.
/// Bikes to filter.
/// Filtered bikes.
public static Dictionary DoFilter(BikeCollection bikes, IEnumerable filter)
{
return bikes.Where(x => x.Group.Intersect(filter).Count() > 0).ToDictionary(x => x.Id);
}
/// Filter stations by group.
///
public static Dictionary DoFilter(StationDictionary stations, IEnumerable p_oFilter)
{
return stations.Where(x => x.Group.Intersect(p_oFilter).Count() > 0).ToDictionary(x => x.Id);
}
}
}
}