tbf/TBF/Rig/BridgeComponents/GciBridge/UI/StaraTuraAPI_GciBridge/CombinedInterfaceView.cs

258 lines
8.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using GciPublicModels = GenesisCordonelInterface.API.PublicModels;
using GenesisCordonelInterface.Core.Threading;
using TBF.Rig.BridgeComponents.GciBridge.Interfaces;
namespace TBF.Rig.BridgeComponents.GciBridge.UI.StaraTuraAPI_GciBridge
{
public partial class CombinedInterfaceView : UserControl
{
private readonly MainView _mainView;
private readonly GciBridge _bridge;
private CancellationTokenSource _cts;
private readonly Dictionary<int, string> _pcbBySlot = new Dictionary<int, string>();
private readonly Dictionary<int, string> _passwordBySlot = new Dictionary<int, string>();
public CombinedInterfaceView(MainView mainView, GciBridge bridge)
{
_mainView = mainView ?? throw new ArgumentNullException(nameof(mainView));
_bridge = bridge ?? throw new ArgumentNullException(nameof(bridge));
InitializeComponent();
}
private List<GciPublicModels.MeterBatchDebugStatus> GetSelectedSlots()
{
var slots = _mainView._batchPanel.GetSelectedGridData();
if (slots.Count == 0)
throw new Exception("No selected slots in grid.");
return slots;
}
private void btnGetPcb_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
_pcbBySlot.Clear();
var slots = GetSelectedSlots().ToList();
var tasks = slots.Select(async slot =>
{
//var result = await _bridge.GetPcbIdAsync(slot.Slot, token);
var result = await _bridge.GetPcbIdWithRetryAsync(slot.Slot, token);
return new
{
Slot = slot.Slot,
Result = result
};
}).ToList();
var results = await Task.WhenAll(tasks);
foreach (var item in results.OrderBy(x => x.Slot))
{
LogResult($"GCI/GetPCB slot {item.Slot}", item.Result);
if (item.Result != null &&
item.Result.Success &&
!string.IsNullOrWhiteSpace(item.Result.Result.PcbId))
{
_pcbBySlot[item.Slot] = item.Result.Result.PcbId;
Log($"Stored PCB: Slot={item.Slot}, PCB={item.Result.Result.PcbId}");
}
}
Log($"PCB stored count: {_pcbBySlot.Count}");
});
}
private void btnGetPasswordByPcb_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
if (_pcbBySlot.Count == 0)
throw new Exception("No PCB values stored. Run GCI/GetPCB first.");
_passwordBySlot.Clear();
foreach (var item in _pcbBySlot.ToList())
{
int slot = item.Key;
string pcbId = item.Value;
//var result = await _bridge.GetPasswordAsync(pcbId, token);
var result = await _bridge.GetPasswordWithRetryAsync(pcbId, token);
LogResult($"UDSR/GetPassword slot {slot}, PCB={pcbId}", result);
if (result != null &&
result.Success &&
!string.IsNullOrWhiteSpace(result.Result.Password))
{
_passwordBySlot[slot] = result.Result.Password;
Log($"Stored password: Slot={slot}, PCB={pcbId}, Password=hidden");
}
}
Log($"Password stored count: {_passwordBySlot.Count}");
});
}
private void btnSetPasswordByPcb_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
if (_passwordBySlot.Count == 0)
throw new Exception("No passwords stored. Run UDSR/GetPassword first.");
foreach (var item in _passwordBySlot.ToList())
{
int slot = item.Key;
string password = item.Value;
//var result = await _bridge.SetPasswordAsync(slot, password, token);
var result = await _bridge.SetPasswordWithRetryAsync(slot, password, token);
LogResult($"GCI/SetPassword slot {slot}", result);
}
RefreshGrid();
});
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (_cts != null)
_cts.Cancel();
Log("Cancel requested.");
}
private async void ExecuteAsync(Func<CancellationToken, Task> action)
{
try
{
SetBusy(true);
_cts = new CancellationTokenSource();
await action(_cts.Token);
}
catch (OperationCanceledException)
{
Log("Operation canceled.");
}
catch (Exception ex)
{
Log("ERROR: " + ex);
MessageBox.Show(
ex.Message,
"Combined API call failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
if (_cts != null)
{
_cts.Dispose();
_cts = null;
}
SetBusy(false);
}
}
private void SetBusy(bool busy)
{
Cursor = busy ? Cursors.WaitCursor : Cursors.Default;
btnGetPcb.Enabled = !busy;
btnGetPasswordByPcb.Enabled = !busy;
btnSetPasswordByPcb.Enabled = !busy;
btnCancel.Enabled = busy;
}
private void RefreshGrid()
{
if (_bridge.gciExternalInterface != null)
_bridge.gciExternalInterface.RaiseMeterBatchStatusChanged();
}
private void LogResult(string methodName, object result)
{
Log(methodName + " result:");
Log(result == null ? "<null>" : result.ToString());
}
private void Log(string message)
{
txtLog.AppendText(
DateTime.Now.ToString("HH:mm:ss.fff") +
" " +
message +
Environment.NewLine);
}
private void button3_Click(object sender, EventArgs e)
{
ExecuteAsync(async token =>
{
var selectedSlots = GetSelectedSlots().ToList();
var tasks = selectedSlots.Select(async slot =>
{
var result = await _bridge.ConnectFullPassLoginWithRetryAsync(slot.Slot, token);
LogResult($"ConnectFullPassLoginAsync slot {slot.Slot}", result);
LogFullLoginResult(result);
return result;
}).ToList();
await Task.WhenAll(tasks);
RefreshGrid();
});
}
private void LogFullLoginResult(PublicModels.GciFullLoginResult result)
{
Log($"====================== SLOT {result.SlotId} ======================");
Log($"FullLogin Success={result.Success}, Message={result.Message}");
LogRetryResult("Connect", result.ConnectResult);
LogRetryResult("GetPcbId", result.PcbResult);
LogRetryResult("GetPassword", result.PasswordResult);
LogRetryResult("SetPassword", result.SetPasswordResult);
LogRetryResult("Login", result.LoginResult);
}
private void LogRetryResult<T>(
string operationName,
RetryResult<T> retryResult)
{
if (retryResult == null)
{
Log($"{operationName}: <not executed>");
return;
}
LogResult(
$"{operationName} | success={retryResult.Success} | attempts={retryResult.Attempts} | duration={retryResult.Duration.TotalSeconds:F1}s | timeout={retryResult.TimedOut}",
retryResult.Result);
}
}
}