using System;
using System.Collections.Generic;
using System.Linq;
namespace StardewModdingAPI.Toolkit.Framework.ModData
{
/// The parsed mod metadata from SMAPI's internal mod list.
public class ModDataRecord
{
/*********
** Accessors
*********/
/// The mod's default display name.
public string DisplayName { get; }
/// The mod's current unique ID.
public string ID { get; }
/// The former mod IDs (if any).
public string[] FormerIDs { get; }
/// The mod warnings to suppress, even if they'd normally be shown.
public ModWarning SuppressWarnings { get; }
/// The versioned field data.
public ModDataField[] Fields { get; }
/*********
** Public methods
*********/
/// Construct an instance.
/// The mod's default display name.
/// The raw data model.
internal ModDataRecord(string displayName, ModDataModel model)
{
this.DisplayName = displayName;
this.ID = model.ID;
this.FormerIDs = model.GetFormerIDs().ToArray();
this.SuppressWarnings = model.SuppressWarnings;
this.Fields = model.GetFields().ToArray();
}
/// Get whether the mod has (or previously had) the given ID.
/// The mod ID.
public bool HasID(string id)
{
// try main ID
if (this.ID.Equals(id, StringComparison.OrdinalIgnoreCase))
return true;
// try former IDs
foreach (string formerID in this.FormerIDs)
{
if (formerID.Equals(id, StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}
/// Get the possible mod IDs.
public IEnumerable GetIDs()
{
return this.FormerIDs
.Concat(new[] { this.ID })
.Where(p => !string.IsNullOrWhiteSpace(p))
.Select(p => p.Trim())
.Distinct();
}
/// Get the default update key for this mod, if any.
public string? GetDefaultUpdateKey()
{
string? updateKey = this.Fields.FirstOrDefault(p => p.Key == ModDataFieldKey.UpdateKey && p.IsDefault)?.Value;
return !string.IsNullOrWhiteSpace(updateKey)
? updateKey
: null;
}
/// Get a parsed representation of the which match a given manifest.
/// The manifest to match.
public ModDataRecordVersionedFields GetVersionedFields(IManifest? manifest)
{
ModDataRecordVersionedFields parsed = new(this);
foreach (ModDataField field in this.Fields.Where(field => field.IsMatch(manifest)))
{
switch (field.Key)
{
// update key
case ModDataFieldKey.UpdateKey:
parsed.UpdateKey = field.Value;
break;
// status
case ModDataFieldKey.Status:
parsed.Status = (ModStatus)Enum.Parse(typeof(ModStatus), field.Value, ignoreCase: true);
parsed.StatusUpperVersion = field.UpperVersion;
break;
// status reason phrase
case ModDataFieldKey.StatusReasonPhrase:
parsed.StatusReasonPhrase = field.Value;
break;
// status technical reason
case ModDataFieldKey.StatusReasonDetails:
parsed.StatusReasonDetails = field.Value;
break;
}
}
return parsed;
}
}
}