#region Header

// Copyright (c) 2021-2025 AccelByte Inc. All Rights Reserved.
// This is licensed software from AccelByte Inc, for limitations
// and restrictions contact your company contract manager.

#endregion

using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using UnityEngine;
#if UNITY_EDITOR
    using UnityEditor;
#endif

namespace BlackBox
{
    public static class HeartbeatManager
    {
        private static NamedPipeClientStream pipeClient;
        private static StreamWriter writer;
        private static bool is_heartbeat_running = false;
        private static Thread heartbeatThread;

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
        private static void OnGameStart()
        {
#if UNITY_STANDALONE_WIN
            if (Application.platform == RuntimePlatform.WindowsPlayer)
            {
                StartHeartbeat();
            }
#endif
        }

#if UNITY_EDITOR
    [InitializeOnLoadMethod]
    private static void Init()
    {
        EditorApplication.playModeStateChanged += OnPlayModeChanged;
    }

    private static void OnPlayModeChanged(PlayModeStateChange state)
    {
        if (state == PlayModeStateChange.EnteredPlayMode)
        {
            StartHeartbeat();
        }
        else if (state == PlayModeStateChange.ExitingPlayMode)
        {
            StopHeartbeat();
        }
    }
#endif

        private static void StartHeartbeat()
        {
            if (is_heartbeat_running) return;
            is_heartbeat_running = true;
            Logger.Log("Starting Helper heartbeat...");

            heartbeatThread = new Thread(() =>
            {
                while (is_heartbeat_running)
                {
                    if (pipeClient == null || !pipeClient.IsConnected)
                    {
                        pipeClient?.Dispose();

                        try
                        {
                            pipeClient = new NamedPipeClientStream(".", "ABBlackBoxUnitySDKHeartbeat", PipeDirection.Out);
                            pipeClient.Connect();
                            writer = new StreamWriter(pipeClient) { AutoFlush = true };
                        }
                        catch (Exception ex)
                        {
                            Logger.LogWarning($"Failed to start Helper heartbeat: {ex.Message}. Crash video would not been created!");
                            Thread.Sleep(5000);
                            continue;
                        }
                    }

                    try
                    {
                        // Sent heartbeat every 500 milliseconds
                        writer.WriteLine("alive\0");
                    }
                    catch (Exception ex)
                    {
                        Logger.LogWarning($"Failed to send Helper heartbeat: {ex.Message}. Crash video would not been created!\nPlease Restart your Unity Editor");
                        pipeClient.Dispose();
                        pipeClient = null;
                    }
                    Thread.Sleep(500);
                }
            })
            {
                IsBackground = true
            };
            heartbeatThread.Start();
        }

        private static void StopHeartbeat()
        {
            if (!is_heartbeat_running) return;
            is_heartbeat_running = false;
            writer?.Close();
            pipeClient?.Close();
            Logger.Log("Stopping Helper heartbeat...");
        }
    }
}
