using System.IO;
using System.Text;
using PCL.Core.IO;
using PCL.Core.Logging;
using PCL.Core.Utils.Codecs;

namespace PCL;

internal static class CrashFileIo
{
    public static byte[] ReadBytes(string filePath)
    {
        try
        {
            // 使用 FileShare.ReadWrite 以读取正在被 Logger 写入的文件
            using var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            using var ms = new MemoryStream();
            fs.CopyTo(ms);
            return ms.ToArray();
        }
        catch (Exception ex)
        {
            LogWrapper.Warn(ex, "Crash IO", "读取与游戏崩溃关联的日志文件时出错，");
            return Files.ReadAllBytesOrEmptyAsync(filePath).GetAwaiter().GetResult();
        }
    }

    public static string ReadText(string filePath, Encoding? encoding = null)
    {
        var bytes = ReadBytes(filePath);
        return encoding is null
            ? EncodingUtils.DecodeBytes(bytes)
            : encoding.GetString(bytes);
    }

    public static void WriteText(string filePath, string text, Encoding? encoding = null)
    {
        Files.WriteFileAsync(filePath, text, encoding: encoding).GetAwaiter().GetResult();
    }

    public static void CopyFile(string fromPath, string toPath)
    {
        Files.CopyFileAsync(fromPath, toPath).GetAwaiter().GetResult();
    }

    public static void DeleteDirectory(string directoryPath)
    {
        Directories.DeleteDirectoryAsync(directoryPath, true).GetAwaiter().GetResult();
    }

    public static bool CanExtractArchive(string archivePath)
    {
        var fileName = Path.GetFileName(archivePath);
        return fileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) ||
               fileName.EndsWith(".gz", StringComparison.OrdinalIgnoreCase) ||
               fileName.EndsWith(".bz2", StringComparison.OrdinalIgnoreCase);
    }

    public static void ExtractFile(string archivePath, string destinationDirectory)
    {
        if (!CanExtractArchive(archivePath))
            throw new NotSupportedException("崩溃日志导入不支持该压缩格式。支持 zip、gz、bz2、tar、tgz 与 tar.gz。");

        Files.ExtractFileAsync(archivePath, destinationDirectory).GetAwaiter().GetResult();
    }
}