/// <summary>
    /// Gets a value indicating if the file should be compressed
    /// </summary>
    /// <param name="entry">The file entry to check</param>
    /// <returns>True if the file should be compressed, otherwise false</returns>
    public bool ShouldCompress(BundleFile_FileEntry entry)
    {
        return(CompressionMode switch
        {
            FileCompressionMode.Never => false,
            FileCompressionMode.Always => true,

            FileCompressionMode.MatchesSetting => !CompressEntireBlock && CompressedFileExtensions.Any(x => x == new FileExtension(entry.Path.FileName, multiple: true)),
            FileCompressionMode.WasCompressed => entry.IsCompressed,

            _ => throw new ArgumentOutOfRangeException(nameof(CompressionMode), CompressionMode, null)
        });
    /// <summary>
    /// Writes the files to the archive
    /// </summary>
    /// <param name="generator">The generator</param>
    /// <param name="archive">The loaded archive data</param>
    /// <param name="outputFileStream">The file output stream for the archive</param>
    /// <param name="files">The files to include</param>
    public void WriteArchive(IDisposable?generator, object archive, ArchiveFileStream outputFileStream, IList <ArchiveFileItem> files)
    {
        Logger.Info("An IPK archive is being repacked...");

        // Get the archive data
        var data = (BundleFile)archive;

        // Create the file generator
        using ArchiveFileGenerator <BundleFile_FileEntry> fileGenerator = new();

        // Get files and entries
        var archiveFiles = files.Select(x => new
        {
            Entry    = (BundleFile_FileEntry)x.ArchiveEntry,
            FileItem = x
        }).ToArray();

        // Set the files
        data.FilePack.Files        = archiveFiles.Select(x => x.Entry).ToArray();
        data.BootHeader.FilesCount = (uint)data.FilePack.Files.Length;

        // Save the old base offset
        uint oldBaseOffset = data.BootHeader.BaseOffset;

        // Keep track of the current pointer position
        ulong currentOffset = 0;

        // Handle each file
        foreach (var file in archiveFiles)
        {
            // Get the file
            BundleFile_FileEntry entry = file.Entry;

            // Reset the offset array to always contain 1 item
            entry.Offsets = new ulong[]
            {
                entry.Offsets?.FirstOrDefault() ?? 0
            };

            // Set the count
            entry.OffsetsCount = (uint)entry.Offsets.Length;

            // Add to the generator
            fileGenerator.Add(entry, () =>
            {
                // When reading the original file we need to use the old base offset
                uint newBaseOffset         = data.BootHeader.BaseOffset;
                data.BootHeader.BaseOffset = oldBaseOffset;

                // Get the file bytes to write to the archive
                Stream fileStream = file.FileItem.GetFileData(generator).Stream;

                data.BootHeader.BaseOffset = newBaseOffset;

                // Set the offset
                entry.Offsets[0] = currentOffset;

                // Increase by the file size
                currentOffset += entry.ArchiveSize;

                // Invoke event
                OnWritingFileToArchive?.Invoke(this, new ValueEventArgs <ArchiveFileItem>(file.FileItem));

                return(fileStream);
            });
        }

        BinaryFile binaryFile = new StreamFile(Context, outputFileStream.Name, outputFileStream.Stream, leaveOpen: true);

        try
        {
            Context.AddFile(binaryFile);

            // Initialize the data
            data.Init(binaryFile.StartPointer);

            // Set the base offset
            data.RecalculateSize();
            data.BootHeader.BaseOffset = (uint)data.Size;

            // Write the files
            WriteArchiveContent(data, outputFileStream.Stream, fileGenerator, Config.ShouldCompress(data.BootHeader));

            outputFileStream.Stream.Position = 0;

            // Serialize the data
            FileFactory.Write(Context, binaryFile.FilePath, data);

            Logger.Info("The IPK archive has been repacked");
        }
        finally
        {
            Context.RemoveFile(binaryFile);
        }
    }