using System;
using System.IO;
using System.Runtime.InteropServices;

namespace ModpackLauncher.Services;

public static class SystemInfo
{
    private const long DefaultFallbackKB = 8L * 1024 * 1024; // assume 8 GB if detection fails

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetPhysicallyInstalledSystemMemory(out long memoryInKilobytes);

    /// <summary>Total physically installed system RAM in megabytes.</summary>
    public static int TotalPhysicalMemoryMB
    {
        get
        {
            try
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    if (GetPhysicallyInstalledSystemMemory(out var kb))
                        return (int)(kb / 1024);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    // Read MemTotal from /proc/meminfo
                    foreach (var line in File.ReadAllLines("/proc/meminfo"))
                    {
                        if (line.StartsWith("MemTotal:", StringComparison.Ordinal))
                        {
                            var parts = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
                            if (parts.Length >= 2 && long.TryParse(parts[1], out var memKb))
                                return (int)(memKb / 1024);
                        }
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    // GC heap-size hint; not perfect but a reasonable fallback for macOS.
                    var gcInfo = GC.GetGCMemoryInfo();
                    if (gcInfo.TotalAvailableMemoryBytes > 0)
                        return (int)(gcInfo.TotalAvailableMemoryBytes / (1024 * 1024));
                }
            }
            catch
            {
                // Fall through to default
            }
            return (int)(DefaultFallbackKB / 1024);
        }
    }

    /// <summary>Recommended max user-allocatable RAM (leaves headroom for OS + other apps).</summary>
    public static int SafeMaxAllocationMB
    {
        get
        {
            var total = TotalPhysicalMemoryMB;
            // Leave at least 4 GB for OS + browser + Discord + everything else.
            var headroom = total >= 32 * 1024 ? 6 * 1024 : 4 * 1024;
            return Math.Max(2048, total - headroom);
        }
    }
}
