using System;
using System.Collections.Generic;
namespace UnityTcp.Editor.Helpers
{
///
/// Provides static methods for creating standardized success and error response objects.
/// Ensures consistent JSON structure for communication back to the Codely client.
///
/// Response format aligns with the OpenAPI spec:
/// - ImmediateResponse: { success, message, data?, state?, state_delta? }
/// - PendingResponse: { _mcp_status, op_id, poll_interval, message, state?, state_delta? }
///
public static class Response
{
///
/// Creates a standardized success response object with optional state.
///
/// A message describing the successful operation.
/// Optional additional data to include in the response.
/// Whether to include full state snapshot (default: false).
/// Optional state delta for incremental updates.
/// An object representing the success response.
public static object Success(string message, object data = null, bool includeState = false, object stateDelta = null)
{
var response = new Dictionary
{
{ "success", true },
{ "message", message },
// Always include current state revision so clients can keep client_state_rev in sync
{ "rev", StateComposer.GetCurrentRevision() }
};
if (data != null)
{
response["data"] = data;
}
// Include state if explicitly requested
if (includeState)
{
response["state"] = StateComposer.BuildFullState();
}
// Include state_delta if provided
if (stateDelta != null)
{
response["state_delta"] = stateDelta;
}
return response;
}
///
/// Creates a standardized success response with automatic state delta.
/// Use this for write operations that modify Unity state.
///
public static object SuccessWithDelta(string message, object data = null, object stateDelta = null)
{
StateComposer.IncrementRevision();
return Success(message, data, includeState: false, stateDelta: stateDelta);
}
///
/// Creates a standardized success response with full state snapshot.
/// Use this for operations that require the client to have the latest state.
///
public static object SuccessWithState(string message, object data = null)
{
StateComposer.IncrementRevision();
return Success(message, data, includeState: true);
}
///
/// Creates a standardized error response object.
///
/// A message describing the error.
/// Optional additional data (e.g., error details) to include.
/// Whether to include full state snapshot for recovery (default: false).
/// An object representing the error response.
public static object Error(string errorCodeOrMessage, object data = null, bool includeState = false)
{
var response = new Dictionary
{
{ "success", false },
{ "code", errorCodeOrMessage },
{ "error", errorCodeOrMessage }
};
if (data != null)
{
response["data"] = data;
}
// Include state on error for recovery scenarios
if (includeState)
{
response["state"] = StateComposer.BuildFullState();
}
return response;
}
///
/// Creates a conflict response for state revision mismatches.
/// This is returned when client_state_rev doesn't match server's revision.
///
/// The client's provided revision.
/// The server's current revision.
/// A conflict response with full state for synchronization.
public static object Conflict(int clientRev, int serverRev)
{
return new Dictionary
{
{ "success", false },
{ "code", "state_revision_conflict" },
{ "error", $"State revision mismatch. Client: {clientRev}, Server: {serverRev}. Please refresh state." },
{ "state", StateComposer.BuildFullState() }
};
}
///
/// Legacy overload for backward compatibility.
///
[Obsolete("Use Success(message, data, includeState, stateDelta) instead.")]
public static object SuccessLegacy(string message, object data = null)
{
if (data != null)
{
return new
{
success = true,
message = message,
data = data,
};
}
else
{
return new { success = true, message = message };
}
}
}
}