using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using View_by_Distance.Metadata.Models;
using View_by_Distance.Property.Models.Stateless;
using View_by_Distance.Shared.Models;
using View_by_Distance.Shared.Models.Stateless;

namespace View_by_Distance.Resize.Models;

/// <summary>
// Dictionary<string, int[]>
/// </summary>
public class C_Resize
{

    public List<string> AngleBracketCollection { get; }

    protected readonly string _FileNameExtension;
    public string FileNameExtension => _FileNameExtension;

    private readonly int _TempResolutionWidth;
    private readonly int _TempResolutionHeight;
    private readonly string[] _ValidResolutions;
    private readonly ASCIIEncoding _ASCIIEncoding;
    private readonly bool _OverrideForResizeImages;
    private readonly ImageCodecInfo _ImageCodecInfo;
    private readonly int _OutputResolutionWidthIndex;
    private readonly bool _PropertiesChangedForResize;
    private readonly ConstructorInfo _ConstructorInfo;
    private readonly int _OutputResolutionHeightIndex;
    private readonly EncoderParameters _EncoderParameters;
    private readonly int _OutputResolutionOrientationIndex;
    private readonly bool _ForceResizeLastWriteTimeToCreationTime;
    private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;

    public C_Resize(bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
    {
        _TempResolutionWidth = 3;
        _TempResolutionHeight = 4;
        _OutputResolutionWidthIndex = 0;
        _ImageCodecInfo = imageCodecInfo;
        _OutputResolutionHeightIndex = 1;
        _ASCIIEncoding = new ASCIIEncoding();
        _ValidResolutions = validResolutions;
        _OutputResolutionOrientationIndex = 2;
        _EncoderParameters = encoderParameters;
        _FileNameExtension = filenameExtension;
        AngleBracketCollection = new List<string>();
        _OverrideForResizeImages = overrideForResizeImages;
        _PropertiesChangedForResize = propertiesChangedForResize;
        _ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
        _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
        ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null);
        if (constructorInfo is null)
            throw new Exception();
        _ConstructorInfo = constructorInfo;
    }

    public override string ToString()
    {
        string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
        return result;
    }

    public void SetAngleBracketCollection(Property.Models.Configuration configuration, string cResultsFullGroupDirectory, string sourceDirectory)
    {
        AngleBracketCollection.Clear();
        AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(configuration,
                                                                           sourceDirectory,
                                                                           cResultsFullGroupDirectory,
                                                                           contentDescription: "Resized image",
                                                                           singletonDescription: "Resize dimensions for each resolution",
                                                                           collectionDescription: string.Empty,
                                                                           converted: true));
    }

#pragma warning disable CA1416

    public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetGifLowQuality()
    {
        (ImageCodecInfo, EncoderParameters, string) result;
        System.Drawing.Imaging.ImageFormat imageFormat = System.Drawing.Imaging.ImageFormat.Gif;
        ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
        EncoderParameters encoderParameters = new(1);
        encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
        if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
            throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
        result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
        return result;
    }

    public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetPngLowQuality()
    {
        (ImageCodecInfo, EncoderParameters, string) result;
        System.Drawing.Imaging.ImageFormat imageFormat = System.Drawing.Imaging.ImageFormat.Png;
        ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
        EncoderParameters encoderParameters = new(1);
        encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
        if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
            throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
        result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
        return result;
    }

    public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetTuple(string outputExtension, int outputQuality)
    {
        (ImageCodecInfo, EncoderParameters, string) result;
        System.Drawing.Imaging.ImageFormat imageFormat = outputExtension switch
        {
            ".gif" => System.Drawing.Imaging.ImageFormat.Gif,
            ".jfif" => System.Drawing.Imaging.ImageFormat.Jpeg,
            ".jpe" => System.Drawing.Imaging.ImageFormat.Jpeg,
            ".jpeg" => System.Drawing.Imaging.ImageFormat.Jpeg,
            ".jpg" => System.Drawing.Imaging.ImageFormat.Jpeg,
            ".png" => System.Drawing.Imaging.ImageFormat.Png,
            ".tif" => System.Drawing.Imaging.ImageFormat.Tiff,
            ".tiff" => System.Drawing.Imaging.ImageFormat.Tiff,
            _ => throw new Exception(),
        };
        ImageCodecInfo imageCodecInfo = (from l in ImageCodecInfo.GetImageEncoders() where l.FormatID == imageFormat.Guid select l).First();
        EncoderParameters encoderParameters = new(1);
        // encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(75L, Int32)) 'Default
        // encoderParameters.Param[0] = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, CType(95L, Int32)) 'Paint
        encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, outputQuality);
        if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
            throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
        result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
        return result;
    }

    public static byte[] GetBitmapData(Bitmap bitmap)
    {
        byte[] results;
        Rectangle rectangle = new(0, 0, bitmap.Width, bitmap.Height);
        BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
        IntPtr intPtr = bitmapData.Scan0;
        int length = bitmapData.Stride * bitmap.Height;
        results = new byte[length];
        Marshal.Copy(intPtr, results, 0, length);
        bitmap.UnlockBits(bitmapData);
        return results;
    }

    private void CopyPropertyItems(byte[] bytes, PropertyItem[] propertyItems, Bitmap bitmap)
    {
        bool hasId = false;
        int id = (int)IExif.Tags.DateTimeDigitized;
        int imageWidth = (int)IExif.Tags.ImageWidth;
        int imageLength = (int)IExif.Tags.ImageLength;
        int orientation = (int)IExif.Tags.Orientation;
        foreach (PropertyItem propertyItem in propertyItems)
        {
            if (propertyItem.Id == id)
                hasId = true;
            else if (propertyItem.Id == imageWidth)
                continue;
            else if (propertyItem.Id == imageLength)
                continue;
            else if (propertyItem.Id == orientation)
                continue;
            bitmap.SetPropertyItem(propertyItem);
        }
        if (!hasId)
        {
            PropertyItem propertyItem = (PropertyItem)_ConstructorInfo.Invoke(null);
            propertyItem.Id = id;
            propertyItem.Len = bytes.Length;
            propertyItem.Type = 2;
            propertyItem.Value = bytes;
            bitmap.SetPropertyItem(propertyItem);
        }
    }

    private byte[] SaveResizedSubfile3(MappingFromItem mappingFromItem, int[] resize, bool returnAndDoNotWrite, byte[] bytes)
    {
        byte[] results;
        Bitmap bitmap;
        int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
        using Bitmap temp = new(mappingFromItem.ImageFileHolder.FullName, useIcm: false);
        int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
        PropertyItem[] propertyItems = temp.PropertyItems;
        int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
        bitmap = new(temp, outputResolutionWidth, outputResolutionHeight);
        switch (outputResolutionOrientation) // exif 274
        {
            case 0:
                break;
            case 1:
                break; // 1 = Horizontal (normal)
            case 2:
                bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
                break; // 2 = Mirror horizontal
            case 3:
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break; // 3 = Rotate 180
            case 4:
                bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                break; // 4 = Mirror vertical
            case 5:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
                break; // 5 = Mirror horizontal and rotate 270 CW
            case 6:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break; // 6 = Rotate 90 CW
            case 7:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
                break; // 7 = Mirror horizontal and rotate 90 CW
            case 8:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break; // 8 = Rotate 270 CW
            default:
                break;
        }
        if (returnAndDoNotWrite)
            results = GetBitmapData(bitmap);
        else
        {
            results = Array.Empty<byte>();
            CopyPropertyItems(bytes, propertyItems, bitmap);
            bitmap.Save(mappingFromItem.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
        }
        bitmap.Dispose();
        return results;
    }

    private byte[] SaveResizedSubfile5(MappingFromItem mappingFromItem, int[] resize, bool returnAndDoNotWrite, byte[] bytes)
    {
        byte[] results;
        Bitmap bitmap;
        using Bitmap temp = new(mappingFromItem.ImageFileHolder.FullName, useIcm: false);
        PropertyItem[] propertyItems = temp.PropertyItems;
        int tempResolutionWidth = resize[_TempResolutionWidth];
        int tempResolutionHeight = resize[_TempResolutionHeight];
        int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
        int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
        int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
        bitmap = new(temp, tempResolutionWidth, tempResolutionHeight);
        switch (outputResolutionOrientation) // exif 274
        {
            case 0:
                break;
            case 1:
                break; // 1 = Horizontal (normal)
            case 2:
                bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
                break; // 2 = Mirror horizontal
            case 3:
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break; // 3 = Rotate 180
            case 4:
                bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                break; // 4 = Mirror vertical
            case 5:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
                break; // 5 = Mirror horizontal and rotate 270 CW
            case 6:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break; // 6 = Rotate 90 CW
            case 7:
                bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
                break; // 7 = Mirror horizontal and rotate 90 CW
            case 8:
                bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break; // 8 = Rotate 270 CW
            default:
                break;
        }
        Bitmap preRotated;
        Rectangle rectangle;
        if (tempResolutionHeight < tempResolutionWidth)
            rectangle = new Rectangle((int)((tempResolutionWidth - outputResolutionWidth) * .5), 0, outputResolutionWidth, outputResolutionHeight);
        else
            rectangle = new Rectangle(0, (int)((tempResolutionHeight - outputResolutionHeight) * .5), outputResolutionWidth, outputResolutionHeight);
        using (preRotated = new Bitmap(outputResolutionWidth, outputResolutionHeight))
        {
            using (Graphics graphics = Graphics.FromImage(preRotated))
                graphics.DrawImage(bitmap, new Rectangle(0, 0, outputResolutionWidth, outputResolutionHeight), rectangle, GraphicsUnit.Pixel);
            if (returnAndDoNotWrite)
                results = GetBitmapData(bitmap);
            else
            {
                results = Array.Empty<byte>();
                CopyPropertyItems(bytes, propertyItems, bitmap);
                bitmap.Save(mappingFromItem.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
            }
        }
        bitmap.Dispose();
        return results;
    }

#pragma warning restore CA1416

    private byte[] SaveResizedSubfile(Shared.Models.Property property, MappingFromItem mappingFromItem, int[] resize, bool returnAndDoNotWrite)
    {
        byte[] results;
        // string subFile, Shared.Models.Property property, Shared.Models.FileHolder? fileHolder
        string dateTimeFormat = Shared.Models.Stateless.Methods.IProperty.DateTimeFormat();
        DateTime dateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(property);
        string dateTimeValue = dateTime.ToString(dateTimeFormat);
        byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
        if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)
            throw new Exception();
        if (resize.Length == 3)
            results = SaveResizedSubfile3(mappingFromItem, resize, returnAndDoNotWrite, bytes);
        else if (resize.Length == 5)
            results = SaveResizedSubfile5(mappingFromItem, resize, returnAndDoNotWrite, bytes);
        else
            throw new Exception();
        return results;
    }

    public byte[] GetResizedBytes(string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Shared.Models.Property property, MappingFromItem mappingFromItem, Dictionary<string, int[]> imageResizeKeyValuePairs)
    {
        byte[] results;
        if (!imageResizeKeyValuePairs.ContainsKey(outputResolution))
            throw new Exception();
        int[] resize = imageResizeKeyValuePairs[outputResolution];
        int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
        int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
        int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
        results = SaveResizedSubfile(property, mappingFromItem, resize, returnAndDoNotWrite: true);
        subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
        return results;
    }

    public void SaveResizedSubfile(Property.Models.Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, Shared.Models.Property property, MappingFromItem mappingFromItem, string original, Dictionary<string, int[]> imageResizeKeyValuePairs)
    {
        if (mappingFromItem.ResizedFileHolder is null)
            throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
        if (!imageResizeKeyValuePairs.ContainsKey(original))
            throw new Exception();
        if (!imageResizeKeyValuePairs.ContainsKey(outputResolution))
            throw new Exception();
        FileInfo fileInfo = new(mappingFromItem.ResizedFileHolder.FullName);
        bool check = false;
        int[] resize = imageResizeKeyValuePairs[outputResolution];
        int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
        int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
        int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
        int[] originalCollection = imageResizeKeyValuePairs[original];
        string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata), nameof(C_Resize) };
        List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
        if (_OverrideForResizeImages)
            check = true;
        else if (!fileInfo.Exists)
            check = true;
        if (outputResolutionWidth == originalCollection[_OutputResolutionWidthIndex] && outputResolutionHeight == originalCollection[_OutputResolutionHeightIndex] && outputResolutionOrientation == originalCollection[_OutputResolutionOrientationIndex])
        {
            if (!check && dateTimes.Any() && dateTimes.Max() > fileInfo.CreationTime.AddDays(1))
                check = true;
            if (check)
            {
                if (fileInfo.Exists)
                    File.Delete(fileInfo.FullName);
                File.Copy(mappingFromItem.ImageFileHolder.FullName, fileInfo.FullName);
                item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
                subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
            }
        }
        else
        {
            if (!check && dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
                check = true;
            if (check)
            {
                _ = SaveResizedSubfile(property, mappingFromItem, resize, returnAndDoNotWrite: false);
                item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
                subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
            }
        }
    }

    private static int[] GetCollection(string outputResolution)
    {
        List<int> results = new();
        string[] segments = outputResolution.Split('x');
        results.Add(int.Parse(segments[0]));
        results.Add(int.Parse(segments[1]));
        return results.ToArray();
    }

    private static int GetOrientation(List<KeyValuePair<string, string>> metadataCollection)
    {
        int result;
        const string orientation = nameof(IExif.Tags.Orientation);
        List<string> orientations = (from l in metadataCollection where l.Key.Contains(orientation) select l.Value).ToList();
        if (!orientations.Any())
            result = 0;
        else if (!int.TryParse(orientations[0], out result))
            result = 0;
        return result;
    }

    private Dictionary<string, int[]> GetImageResizes(Shared.Models.Property property, List<KeyValuePair<string, string>> metadataCollection, string original)
    {
        Dictionary<string, int[]> results = new();
        int[] desired;
        int checkWidth;
        int orientation;
        int checkHeight;
        int desiredWidth;
        int desiredHeight;
        if (property is null || property.Width is null || property.Height is null)
            throw new Exception();
        if (!string.IsNullOrEmpty(property.Orientation) && int.TryParse(property.Orientation, out int propertyOrientation))
            orientation = propertyOrientation;
        else
            orientation = GetOrientation(metadataCollection);
        checkWidth = property.Width.Value;
        checkHeight = property.Height.Value;
        results.Add(original, new int[] { checkWidth, checkHeight, orientation });
        foreach (string validResolution in _ValidResolutions)
        {
            desired = GetCollection(validResolution);
            desiredWidth = desired[0];
            desiredHeight = desired[1];
            if (checkWidth <= desiredWidth && checkHeight <= desiredHeight)
                results.Add(validResolution, new int[] { checkWidth, checkHeight, orientation });
            else
            {
                if (desiredWidth != desiredHeight)
                {
                    if (checkWidth * desiredHeight > desiredWidth * checkHeight)
                        results.Add(validResolution, new int[] { desiredWidth, Convert.ToInt32(desiredWidth * checkHeight / (double)checkWidth), orientation });
                    else
                        results.Add(validResolution, new int[] { Convert.ToInt32(desiredHeight * checkWidth / (double)checkHeight), desiredHeight, orientation });
                }
                else
                {
                    if (checkWidth * desiredHeight <= desiredWidth * checkHeight)
                        results.Add(validResolution, new int[] { desiredWidth, desiredHeight, orientation, desiredWidth, Convert.ToInt32(desiredWidth * checkHeight / (double)checkWidth) });
                    else
                        results.Add(validResolution, new int[] { desiredWidth, desiredHeight, orientation, Convert.ToInt32(desiredHeight * checkWidth / (double)checkHeight), desiredHeight });
                }
            }
        }
        return results;
    }

    public FileHolder GetResizedFileHolder(Item item)
    {
        FileHolder result = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(item.ImageFileHolder.FullName)));
        return result;
    }

    public Dictionary<string, int[]> GetResizeKeyValuePairs(Property.Models.Configuration configuration, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string original, List<KeyValuePair<string, string>> metadataCollection, Shared.Models.Property property, MappingFromItem mappingFromItem)
    {
        Dictionary<string, int[]> results;
        string json;
        string[] changesFrom = new string[] { nameof(Property.Models.A_Property), nameof(B_Metadata) };
        List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
        string cResizeSingletonFile = Path.Combine(cResultsFullGroupDirectory, "{}", configuration.ResultAllInOne, $"{mappingFromItem.Id}{mappingFromItem.ImageFileHolder.ExtensionLowered}.json");
        FileInfo fileInfo = new(cResizeSingletonFile);
        if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
        {
            File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
            fileInfo.Refresh();
        }
        if (_ForceResizeLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
        {
            File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
            fileInfo.Refresh();
        }
        if (_PropertiesChangedForResize)
            results = new();
        else if (!fileInfo.Exists)
            results = new();
        else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old"))
            throw new ArgumentException("must be a *.json file");
        else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
            results = new();
        else
        {
            json = File.ReadAllText(fileInfo.FullName);
            try
            {
                Dictionary<string, int[]>? keyValuePairs;
                keyValuePairs = JsonSerializer.Deserialize<Dictionary<string, int[]>>(json);
                if (keyValuePairs is null)
                    throw new Exception();
                results = keyValuePairs;
                if ((from l in results where l.Value[0] == l.Value[1] select true).Any())
                {
                    results = GetImageResizes(property, metadataCollection, original);
                    if (!(from l in results where l.Value[0] == l.Value[1] select true).Any())
                        throw new Exception("Was square!");
                }
                subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), fileInfo.LastWriteTime));
            }
            catch (Exception)
            {
                results = new();
                parseExceptions.Add(nameof(C_Resize));
            }
        }
        if (results is null || !results.Any())
        {
            results = GetImageResizes(property, metadataCollection, original);
            json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
            bool updateDateWhenMatches = dateTimes.Any() && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
            DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
            if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
            {
                if (!_ForceResizeLastWriteTimeToCreationTime)
                    subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
                else
                {
                    File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
                    fileInfo.Refresh();
                    subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), fileInfo.CreationTime));
                }
            }
        }
        return results;
    }

    public static byte[] GetBytes(string value)
    {
        byte[] results = new byte[value.Length + 1];
        for (int i = 0; i < value.Length; i++)
            results[i] = (byte)value[i];
        results[value.Length] = 0x00;
        return results;
    }

}