using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace ivf_tl_Operate.Debug
{
///
/// operate 端"16 孔标定协作"客户端:封装 control 的 /debug/calibrate/* 四端点(start/progress/recalibrate/stop)
/// + 轮询进度。复用 operate 已借到的 sessionId(由 DebugSessionClient.Acquire 取得),全程同一会话。
/// 纯逻辑可单测:HttpClient 可注入(测试用 FakeHandler);http=null 则自建并自 Dispose(对齐 DebugSessionClient)。
/// start/recalibrate/stop 返回 AcquireResult(对齐 control DebugCommandResult:Ok/Result/Error/Code);
/// progress 返回 CalibProgressDto(从 DebugCommandResult.result 内嵌对象反序列化)。
/// 实时画面复用 MjpegStreamClient(不在本类)。
///
public sealed class CalibrationClient : IDisposable
{
private readonly string _baseUrl;
private readonly string _sessionId;
private readonly HttpClient _http;
private readonly bool _ownsHttp;
public CalibrationClient(string baseUrl, string sessionId, HttpClient http = null)
{
_baseUrl = baseUrl.TrimEnd('/');
_sessionId = sessionId;
_ownsHttp = http == null; // 自建的由本类 Dispose;注入的归调用方
_http = http ?? new HttpClient();
}
// /progress 的 result 内嵌 CalibProgress,用 envelope 把外层 ok/code 与内层 result 一并取出。
private sealed class ProgressEnvelope
{
[JsonProperty("ok")] public bool Ok { get; set; }
[JsonProperty("code")] public string Code { get; set; }
[JsonProperty("error")] public string Error { get; set; }
[JsonProperty("result")] public CalibProgressDto Result { get; set; }
}
private async Task PostAsync(string path, object body)
{
var content = new StringContent(body == null ? "{}" : JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
var resp = await _http.PostAsync($"{_baseUrl}{path}", content);
string s = await resp.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject(s) ?? new AcquireResult { Ok = false, Error = "空响应" };
}
/// 起一次 16 孔标定。wells 为空则 control 端默认 1..16。
public Task StartAsync(IEnumerable wells = null)
=> PostAsync("/debug/calibrate/start", new { sessionId = _sessionId, wells = wells?.ToArray() });
/// 轮询进度:返回 CalibProgressDto(无进度/会话失效则返回 null)。
public async Task PollProgressAsync()
{
var content = new StringContent(JsonConvert.SerializeObject(new { sessionId = _sessionId }), Encoding.UTF8, "application/json");
var resp = await _http.PostAsync($"{_baseUrl}/debug/calibrate/progress", content);
string s = await resp.Content.ReadAsStringAsync();
var env = JsonConvert.DeserializeObject(s);
return env?.Result; // ok=false(SESSION_EXPIRED 等)时 result 缺省 → null
}
/// 单孔重标。
public Task RecalibrateAsync(int wellSn)
=> PostAsync("/debug/calibrate/recalibrate", new { sessionId = _sessionId, wellSn });
/// 中止标定。
public Task StopAsync()
=> PostAsync("/debug/calibrate/stop", new { sessionId = _sessionId });
public void Dispose()
{
if (_ownsHttp) { try { _http?.Dispose(); } catch { } } // 只释放自建的;注入的归调用方
}
}
}