using System;
using System.IO;
using System.Security.Cryptography;
using UnityEngine;

namespace UnityAssistant
{
    public static class BridgeAuth
    {
        private const string HeaderName = "X-Unity-Assistant-Token";
        private static string _token;

        public static string Token => _token ?? (_token = LoadOrCreateToken());

        public static bool IsAuthorized(System.Net.HttpListenerRequest request)
        {
            var expected = Token;
            if (string.IsNullOrEmpty(expected)) return true;
            var provided = request.Headers[HeaderName];
            return !string.IsNullOrEmpty(provided) && SlowEquals(provided, expected);
        }

        private static string LoadOrCreateToken()
        {
            try
            {
                var path = TokenPath();
                var dir = Path.GetDirectoryName(path);
                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
                if (File.Exists(path))
                {
                    var existing = File.ReadAllText(path).Trim();
                    if (existing.Length >= 32) return existing;
                }

                var bytes = new byte[32];
                using (var rng = RandomNumberGenerator.Create())
                    rng.GetBytes(bytes);
                var token = Convert.ToBase64String(bytes);
                File.WriteAllText(path, token);
                return token;
            }
            catch (Exception e)
            {
                Debug.LogWarning("[Gumo] Bridge auth token unavailable: " + e.Message);
                return "";
            }
        }

        private static string TokenPath()
        {
            var local = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            return Path.Combine(local, "UnityAssistant", "bridge-token.txt");
        }

        private static bool SlowEquals(string a, string b)
        {
            if (a == null || b == null) return false;
            var diff = a.Length ^ b.Length;
            var n = Math.Min(a.Length, b.Length);
            for (int i = 0; i < n; i++) diff |= a[i] ^ b[i];
            return diff == 0;
        }
    }
}
