using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.StationRecords;
namespace Content.Server.StationRecords;
///
/// Set of station records. StationRecordsComponent stores these.
/// Keyed by StationRecordKey, which should be obtained from
/// an entity that stores a reference to it.
///
public sealed class StationRecordSet
{
private uint _currentRecordId;
private HashSet _keys = new();
private HashSet _recentlyAccessed = new();
[ViewVariables]
private Dictionary> _tables = new();
///
/// Gets all records of a specific type stored in the record set.
///
/// The type of record to fetch.
/// An enumerable object that contains a pair of both a station key, and the record associated with it.
public IEnumerable<(StationRecordKey, T)> GetRecordsOfType()
{
if (!_tables.ContainsKey(typeof(T)))
{
yield break;
}
foreach (var (key, entry) in _tables[typeof(T)])
{
if (entry is not T cast)
{
continue;
}
_recentlyAccessed.Add(key);
yield return (key, cast);
}
}
///
/// Add a new record into this set of entries.
///
/// Station that we're adding the record for.
/// A key that represents the record in this set.
public StationRecordKey AddRecord(EntityUid station)
{
var key = new StationRecordKey(_currentRecordId++, station);
_keys.Add(key);
return key;
}
///
/// Add an entry into a record.
///
/// Key for the record.
/// Entry to add.
/// Type of the entry that's being added.
public void AddRecordEntry(StationRecordKey key, T entry)
{
if (!_keys.Contains(key) || entry == null)
{
return;
}
if (!_tables.TryGetValue(typeof(T), out var table))
{
table = new();
_tables.Add(typeof(T), table);
}
table.Add(key, entry);
}
///
/// Try to get an record entry by type, from this record key.
///
/// The StationRecordKey to get the entries from.
/// The entry that is retrieved from the record set.
/// The type of entry to search for.
/// True if the record exists and was retrieved, false otherwise.
public bool TryGetRecordEntry(StationRecordKey key, [NotNullWhen(true)] out T? entry)
{
entry = default;
if (!_keys.Contains(key)
|| !_tables.TryGetValue(typeof(T), out var table)
|| !table.TryGetValue(key, out var entryObject))
{
return false;
}
entry = (T) entryObject;
_recentlyAccessed.Add(key);
return true;
}
///
/// Checks if the record associated with this key has an entry of a certain type.
///
/// The record key.
/// Type to check.
/// True if the entry exists, false otherwise.
public bool HasRecordEntry(StationRecordKey key)
{
return _keys.Contains(key)
&& _tables.TryGetValue(typeof(T), out var table)
&& table.ContainsKey(key);
}
///
/// Get the recently accessed keys from this record set.
///
/// All recently accessed keys from this record set.
public IEnumerable GetRecentlyAccessed()
{
return _recentlyAccessed.ToArray();
}
///
/// Clears the recently accessed keys from the set.
///
public void ClearRecentlyAccessed()
{
_recentlyAccessed.Clear();
}
///
/// Removes all record entries related to this key from this set.
///
/// The key to remove.
/// True if successful, false otherwise.
public bool RemoveAllRecords(StationRecordKey key)
{
if (!_keys.Remove(key))
{
return false;
}
foreach (var table in _tables.Values)
{
table.Remove(key);
}
return true;
}
}