using Avalonia.Platform;
using DodoSSH.Client.Terminal;

namespace DodoSSH.Client.Shell.Terminal;

/// <summary>
/// Serves the renderer's files from the assembly's embedded resources.
/// </summary>
/// <remarks>
/// Read once at startup and cached. The files are a few hundred kilobytes in total, dominated by the
/// xterm bundle, and a terminal that stalled on a resource stream read while output was arriving
/// would be a strange way to save a rounding error of memory.
/// </remarks>
internal sealed class AvaloniaTerminalAssetProvider : ITerminalAssetProvider
{
    private const string ResourceRoot = "avares://DodoSSH.Client.Shell/WebAssets";

    private static readonly (string Path, string File, string ContentType)[] Files =
    [
        (TerminalDataPlane.PagePath, "terminal.html", "text/html; charset=utf-8"),
        ("/terminal.js", "terminal.js", "text/javascript; charset=utf-8"),
        ("/terminal.css", "terminal.css", "text/css; charset=utf-8"),
        ("/vendor/xterm.js", "vendor/xterm.js", "text/javascript; charset=utf-8"),
        ("/vendor/xterm.css", "vendor/xterm.css", "text/css; charset=utf-8"),
        ("/vendor/addon-fit.js", "vendor/addon-fit.js", "text/javascript; charset=utf-8"),
        ("/vendor/addon-webgl.js", "vendor/addon-webgl.js", "text/javascript; charset=utf-8"),
    ];

    private readonly Dictionary<string, TerminalAsset> assets = new(StringComparer.Ordinal);

    internal AvaloniaTerminalAssetProvider()
    {
        foreach (var (path, file, contentType) in Files)
        {
            using var stream = AssetLoader.Open(new Uri($"{ResourceRoot}/{file}", UriKind.Absolute));
            using var buffer = new MemoryStream();
            stream.CopyTo(buffer);

            assets[path] = new TerminalAsset(contentType, buffer.ToArray());
        }
    }

    /// <inheritdoc />
    public TerminalAsset? Find(string path) => assets.GetValueOrDefault(path);
}
