using System;
using System.Collections.Generic;
using System.IO;
#if NET452_OR_GREATER || NETCOREAPP
using System.IO.Compression;
using System.Linq;
#endif
namespace MPF.Processors
{
///
/// Represents attributes about an
///
[Flags]
public enum OutputFileFlags : ushort
{
///
/// Default state
///
None = 0x0000,
///
/// File is required to exist
///
Required = 0x0001,
///
/// File is included as an artifact
///
Artifact = 0x0002,
///
/// File is included as a binary artifact
///
Binary = 0x0004,
///
/// File can be deleted after processing
///
Deleteable = 0x0008,
///
/// File can be zipped after processing
///
Zippable = 0x0010,
}
///
/// Represents a single output file
///
internal class OutputFile
{
///
/// Set of all filename variants
///
public string[] Filenames { get; private set; }
///
/// Key used when creating an artifact
///
public string? ArtifactKey { get; private set; }
///
/// Indicates if the file is required
///
public bool IsRequired
{
get
{
#if NET20 || NET35
return (_flags & OutputFileFlags.Required) != 0;
#else
return _flags.HasFlag(OutputFileFlags.Required);
#endif
}
}
///
/// Indicates if the file is an artifact
///
public bool IsArtifact
{
get
{
#if NET20 || NET35
return (_flags & OutputFileFlags.Artifact) != 0
|| (_flags & OutputFileFlags.Binary) != 0;
#else
return _flags.HasFlag(OutputFileFlags.Artifact)
|| _flags.HasFlag(OutputFileFlags.Binary);
#endif
}
}
///
/// Indicates if the file is a binary artifact
///
public bool IsBinaryArtifact
{
get
{
#if NET20 || NET35
return (_flags & OutputFileFlags.Binary) != 0;
#else
return _flags.HasFlag(OutputFileFlags.Binary);
#endif
}
}
///
/// Indicates if the file is deleteable after processing
///
public bool IsDeleteable
{
get
{
#if NET20 || NET35
return (_flags & OutputFileFlags.Deleteable) != 0;
#else
return _flags.HasFlag(OutputFileFlags.Deleteable);
#endif
}
}
///
/// Indicates if the file is zippable after processing
///
public bool IsZippable
{
get
{
#if NET20 || NET35
return (_flags & OutputFileFlags.Zippable) != 0;
#else
return _flags.HasFlag(OutputFileFlags.Zippable);
#endif
}
}
///
/// Represents attributes about the current file
///
protected readonly OutputFileFlags _flags;
///
/// Create an OutputFile with a single filename
///
public OutputFile(string filename, OutputFileFlags flags)
: this([filename], flags)
{
}
///
/// Create an OutputFile with a single filename
///
public OutputFile(string filename, OutputFileFlags flags, string artifactKey)
: this([filename], flags, artifactKey)
{
}
///
/// Create an OutputFile with set of filenames
///
public OutputFile(string[] filenames, OutputFileFlags flags)
{
Filenames = filenames;
ArtifactKey = null;
_flags = flags;
// Validate the inputs
if (filenames.Length == 0)
throw new ArgumentException($"{nameof(filenames)} must contain at least one value");
if (IsArtifact && string.IsNullOrEmpty(ArtifactKey))
throw new ArgumentException($"{nameof(flags)} should not contain the Artifact or Binary flag");
}
///
/// Create an OutputFile with set of filenames
///
public OutputFile(string[] filenames, OutputFileFlags flags, string artifactKey)
{
Filenames = filenames;
ArtifactKey = artifactKey;
_flags = flags;
// Validate the inputs
if (filenames.Length == 0)
throw new ArgumentException($"{nameof(filenames)} must contain at least one value");
if (IsArtifact && string.IsNullOrEmpty(ArtifactKey))
throw new ArgumentException($"{nameof(flags)} should not contain the Artifact or Binary flag");
}
///
/// Indicates if an output file exists in a base directory
///
/// Base directory to check in
public virtual bool Exists(string outputDirectory)
{
// Ensure the directory exists
if (!Directory.Exists(outputDirectory))
return false;
foreach (string filename in Filenames)
{
// Check for invalid filenames
if (string.IsNullOrEmpty(filename))
continue;
try
{
string possibleFile = Path.Combine(outputDirectory, filename);
if (File.Exists(possibleFile))
return true;
}
catch { }
}
return false;
}
#if NET452_OR_GREATER || NETCOREAPP
///
/// Indicates if an output file exists in an archive
///
/// Zip archive to check in
public virtual bool Exists(ZipArchive? archive)
{
// If the archive is invalid
if (archive == null)
return false;
foreach (string filename in Filenames)
{
// Check for invalid filenames
if (string.IsNullOrEmpty(filename))
continue;
try
{
// Check all entries on filename alone
if (archive.Entries.Any(e => e.Name == filename))
return true;
}
catch { }
}
return false;
}
#endif
///
/// Get all matching paths for the file
///
/// Base directory to check in
public virtual List GetPaths(string outputDirectory)
{
List paths = [];
foreach (string filename in Filenames)
{
string possibleFile = Path.Combine(outputDirectory, filename);
if (!File.Exists(possibleFile))
continue;
paths.Add(possibleFile);
}
return paths;
}
}
}