using System;
using System.Collections.Generic;
using SabreTools.Core.Tools;
using SabreTools.DatItems;
using SabreTools.DatItems.Formats;
namespace SabreTools.DatFiles.Formats
{
///
/// Represents a Logiqx-derived DAT
///
public sealed class Logiqx : SerializableDatFile
{
#region Constants
///
/// DTD for original Logiqx DATs
///
/// This has been edited to reflect actual current standards
private const string LogiqxDTD = @"
";
///
/// XSD for No-Intro Logiqx-derived DATs
///
private const string NoIntroXSD = @"
";
#endregion
#region Fields
///
public override ItemType[] SupportedTypes
=> [
ItemType.Archive,
ItemType.BiosSet,
ItemType.DeviceRef,
ItemType.Disk,
ItemType.Driver,
ItemType.Media,
ItemType.Release,
ItemType.Rom,
ItemType.Sample,
ItemType.SoftwareList,
];
///
/// Indicates if game should be used instead of machine
///
private readonly bool _useGame;
#endregion
///
/// Constructor designed for casting a base DatFile
///
/// Parent DatFile to copy from
/// True if the output uses "game", false if the output uses "machine"
public Logiqx(DatFile? datFile, bool useGame) : base(datFile)
{
_useGame = useGame;
if (useGame)
Header.SetFieldValue(DatHeader.DatFormatKey, DatFormat.LogiqxDeprecated);
else
Header.SetFieldValue(DatHeader.DatFormatKey, DatFormat.Logiqx);
}
///
protected internal override List? GetMissingRequiredFields(DatItem datItem)
{
List missingFields = [];
switch (datItem)
{
case Release release:
if (string.IsNullOrEmpty(release.GetName()))
missingFields.Add(Models.Metadata.Release.NameKey);
if (string.IsNullOrEmpty(release.GetStringFieldValue(Models.Metadata.Release.RegionKey)))
missingFields.Add(Models.Metadata.Release.RegionKey);
break;
case BiosSet biosset:
if (string.IsNullOrEmpty(biosset.GetName()))
missingFields.Add(Models.Metadata.BiosSet.NameKey);
if (string.IsNullOrEmpty(biosset.GetStringFieldValue(Models.Metadata.BiosSet.DescriptionKey)))
missingFields.Add(Models.Metadata.BiosSet.DescriptionKey);
break;
case Rom rom:
if (string.IsNullOrEmpty(rom.GetName()))
missingFields.Add(Models.Metadata.Rom.NameKey);
if (rom.GetInt64FieldValue(Models.Metadata.Rom.SizeKey) == null || rom.GetInt64FieldValue(Models.Metadata.Rom.SizeKey) < 0)
missingFields.Add(Models.Metadata.Rom.SizeKey);
if (string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.CRCKey))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.MD5Key))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.SHA1Key))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.SHA256Key))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.SHA384Key))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.SHA512Key))
&& string.IsNullOrEmpty(rom.GetStringFieldValue(Models.Metadata.Rom.SpamSumKey)))
{
missingFields.Add(Models.Metadata.Rom.SHA1Key);
}
break;
case Disk disk:
if (string.IsNullOrEmpty(disk.GetName()))
missingFields.Add(Models.Metadata.Disk.NameKey);
if (string.IsNullOrEmpty(disk.GetStringFieldValue(Models.Metadata.Disk.MD5Key))
&& string.IsNullOrEmpty(disk.GetStringFieldValue(Models.Metadata.Disk.SHA1Key)))
{
missingFields.Add(Models.Metadata.Disk.SHA1Key);
}
break;
case Media media:
if (string.IsNullOrEmpty(media.GetName()))
missingFields.Add(Models.Metadata.Media.NameKey);
if (string.IsNullOrEmpty(media.GetStringFieldValue(Models.Metadata.Media.MD5Key))
&& string.IsNullOrEmpty(media.GetStringFieldValue(Models.Metadata.Media.SHA1Key))
&& string.IsNullOrEmpty(media.GetStringFieldValue(Models.Metadata.Media.SHA256Key))
&& string.IsNullOrEmpty(media.GetStringFieldValue(Models.Metadata.Media.SpamSumKey)))
{
missingFields.Add(Models.Metadata.Media.SHA1Key);
}
break;
case DeviceRef deviceref:
if (string.IsNullOrEmpty(deviceref.GetName()))
missingFields.Add(Models.Metadata.DeviceRef.NameKey);
break;
case Sample sample:
if (string.IsNullOrEmpty(sample.GetName()))
missingFields.Add(Models.Metadata.Sample.NameKey);
break;
case Archive archive:
if (string.IsNullOrEmpty(archive.GetName()))
missingFields.Add(Models.Metadata.Archive.NameKey);
break;
case Driver driver:
if (driver.GetStringFieldValue(Models.Metadata.Driver.StatusKey).AsSupportStatus() == SupportStatus.NULL)
missingFields.Add(Models.Metadata.Driver.StatusKey);
if (driver.GetStringFieldValue(Models.Metadata.Driver.EmulationKey).AsSupportStatus() == SupportStatus.NULL)
missingFields.Add(Models.Metadata.Driver.EmulationKey);
if (driver.GetStringFieldValue(Models.Metadata.Driver.CocktailKey).AsSupportStatus() == SupportStatus.NULL)
missingFields.Add(Models.Metadata.Driver.CocktailKey);
if (driver.GetStringFieldValue(Models.Metadata.Driver.SaveStateKey).AsSupportStatus() == SupportStatus.NULL)
missingFields.Add(Models.Metadata.Driver.SaveStateKey);
break;
case DatItems.Formats.SoftwareList softwarelist:
if (string.IsNullOrEmpty(softwarelist.GetStringFieldValue(Models.Metadata.SoftwareList.TagKey)))
missingFields.Add(Models.Metadata.SoftwareList.TagKey);
if (string.IsNullOrEmpty(softwarelist.GetName()))
missingFields.Add(Models.Metadata.SoftwareList.NameKey);
if (softwarelist.GetStringFieldValue(Models.Metadata.SoftwareList.StatusKey).AsSoftwareListStatus() == SoftwareListStatus.None)
missingFields.Add(Models.Metadata.SoftwareList.StatusKey);
break;
}
return missingFields;
}
///
public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{
try
{
_logger.User($"Writing to '{outfile}'...");
// Serialize the input file
var metadata = ConvertToMetadata(ignoreblanks);
var datafile = new Serialization.CrossModel.Logiqx().Deserialize(metadata, _useGame);
// TODO: Reenable doctype writing
// Only write the doctype if we don't have No-Intro data
bool success;
if (string.IsNullOrEmpty(Header.GetStringFieldValue(Models.Metadata.Header.IdKey)))
success = Serialization.Serializers.Logiqx.SerializeFile(datafile!, outfile);
else
success = Serialization.Serializers.Logiqx.SerializeFile(datafile, outfile);
if (!success)
{
_logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
return false;
}
}
catch (Exception ex) when (!throwOnError)
{
_logger.Error(ex);
return false;
}
_logger.User($"'{outfile}' written!{Environment.NewLine}");
return true;
}
}
}