namespace MinicsUI.Connector;

public class SenderBase : IDisposable
{
    protected HubConnection? _hubConnection;
    private bool CheckConnect()
    {
        if (_hubConnection is null)
            return false;
        if (_hubConnection.State != HubConnectionState.Connected)
            return false;

        return true;
    }

    protected static bool StartConsole()
    {
        Mutex mutex = new(false, "7E862400-8020-BE75-5266-B2C4BEB54076", out bool flag);

        if (!flag)
        {
            mutex.Dispose();
            return true;
        }

        try
        {
            Process p = new();
            p.StartInfo.FileName = FilePaths.ConsoleExe;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.Start();
        }
        catch
        {
            mutex.Dispose();
            return false;
        }

        mutex.Dispose();
        return true;
    }

    public void Dispose()
    {
        _hubConnection?.StopAsync();
        _hubConnection = null;
    }

    protected async Task<bool> Send(string name)
    {
        if (!CheckConnect())
            return false;

        try
        {
            await _hubConnection!.SendAsync(name);
        }
        catch
        {
            return false;
        }

        return true;
    }

    protected async Task<bool> Send<T1>(string name, T1 para1)
    {
        if (!CheckConnect())
            return false;

        try
        {
            await _hubConnection!.SendAsync(name, para1);
        }
        catch
        {
            return false;
        }

        return true;
    }

    protected async Task<bool> Send<T1, T2>(string name, T1 para1, T2 para2)
    {
        if (!CheckConnect())
            return false;

        try
        {
            await _hubConnection!.SendAsync(name, para1, para2);
        }
        catch
        {
            return false;
        }

        return true;
    }



    protected async Task<bool> Send<T1, T2, T3>(string name, T1 para1, T2 para2, T3 para3)
    {
        if (!CheckConnect())
            return false;

        try
        {
            await _hubConnection!.SendAsync(name, para1, para2, para3);
        }
        catch
        {
            return false;
        }

        return true;
    }

    protected bool Invoke<T_Return>(string name, out T_Return? returnValue)
    {
        returnValue = default;

        if (!CheckConnect())
            return false;

        try
        {
            returnValue = _hubConnection!.InvokeAsync<T_Return>(name).Result;
        }
        catch
        {
            return false;
        }

        return true;
    }

    protected bool Invoke<T_Return, T_para1>(string name, T_para1 para1, out T_Return? returnValue)
    {
        returnValue = default;

        if (!CheckConnect())
            return false;

        try
        {
            returnValue = _hubConnection!.InvokeAsync<T_Return>(name, para1).Result;
        }
        catch
        {
            return false;
        }

        return true;
    }
    protected bool Invoke<T_Return, T_para1, T_Para2>(string name, T_para1 para1, T_Para2 para2, out T_Return? returnValue)
    {
        returnValue = default;

        if (!CheckConnect())
            return false;

        try
        {
            returnValue = _hubConnection!.InvokeAsync<T_Return>(name, para1, para2).Result;
        }
        catch
        {
            return false;
        }

        return true;
    }

    protected bool Invoke<T_Return, T_para1, T_Para2, T_Para3>(string name, T_para1 para1, T_Para2 para2, T_Para3 para3, out T_Return? returnValue)
    {
        returnValue = default;

        if (!CheckConnect())
            return false;

        try
        {
            returnValue = _hubConnection!.InvokeAsync<T_Return>(name, para1, para2, para3).Result;
        }
        catch
        {
            return false;
        }

        return true;
    }
}