using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp.WebScripting;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Core.Web.RequestHandlers;
using PepperDash.Essentials.Core.Config;
using PepperDash.Essentials.WebSocketServer;
namespace PepperDash.Essentials.WebApiHandlers
{
///
/// Represents a MobileInfoHandler. Used with the Essentials CWS API
///
public class MobileInfoHandler : WebApiBaseRequestHandler
{
private readonly MobileControlSystemController mcController;
///
/// Create an instance of the class.
///
///
public MobileInfoHandler(MobileControlSystemController controller) : base(true)
{
mcController = controller;
}
///
/// Get Mobile Control Information
///
///
protected override void HandleGet(HttpCwsContext context)
{
try
{
var response = new InformationResponse(mcController);
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
context.Response.Write(JsonConvert.SerializeObject(response), false);
context.Response.End();
}
catch (Exception ex)
{
Debug.LogMessage(ex, "exception showing mobile info");
context.Response.StatusCode = 500;
context.Response.End();
}
}
}
///
/// Represents a InformationResponse
///
public class InformationResponse
{
[JsonIgnore]
private readonly MobileControlSystemController mcController;
///
/// Edge Server. Null if edge server is disabled
///
[JsonProperty("edgeServer", NullValueHandling = NullValueHandling.Ignore)]
public MobileControlEdgeServer EdgeServer => mcController.Config.EnableApiServer ? new MobileControlEdgeServer(mcController) : null;
///
/// Direct server. Null if the direct server is disabled
///
[JsonProperty("directServer", NullValueHandling = NullValueHandling.Ignore)]
public MobileControlDirectServer DirectServer => mcController.Config.DirectServer.EnableDirectServer ? new MobileControlDirectServer(mcController.DirectServer) : null;
///
/// Create an instance of the class.
///
///
public InformationResponse(MobileControlSystemController controller)
{
mcController = controller;
}
}
///
/// Represents a MobileControlEdgeServer
///
public class MobileControlEdgeServer
{
[JsonIgnore]
private readonly MobileControlSystemController mcController;
///
/// Mobile Control Edge Server address for this system
///
[JsonProperty("serverAddress")]
public string ServerAddress => mcController.Config == null ? "No Config" : mcController.Host;
///
/// System Name for this system
///
[JsonProperty("systemName")]
public string SystemName => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].RoomName : "No Config";
///
/// System URL for this system
///
[JsonProperty("systemUrl")]
public string SystemUrl => ConfigReader.ConfigObject.SystemUrl;
///
/// User code to use in MC UI for this system
///
[JsonProperty("userCode")]
public string UserCode => mcController.RoomBridges.Count > 0 ? mcController.RoomBridges[0].UserCode : "Not available";
///
/// True if connected to edge server
///
[JsonProperty("connected")]
public bool Connected => mcController.Connected;
///
/// Seconds since last comms with edge server
///
[JsonProperty("secondsSinceLastAck")]
public int SecondsSinceLastAck => (DateTime.Now - mcController.LastAckMessage).Seconds;
///
/// Create an instance of the class.
///
/// controller to use for this
public MobileControlEdgeServer(MobileControlSystemController controller)
{
mcController = controller;
}
}
///
/// Represents a MobileControlDirectServer
///
public class MobileControlDirectServer
{
[JsonIgnore]
private readonly MobileControlWebsocketServer directServer;
///
/// URL to use to interact with this server
///
[JsonProperty("userAppUrl")]
public string UserAppUrl => $"{directServer.UserAppUrlPrefix}/[insert_client_token]";
///
/// TCP/IP Port this server is configured to use
///
[JsonProperty("serverPort")]
public int ServerPort => directServer.Port;
///
/// Count of defined tokens for this server
///
[JsonProperty("tokensDefined")]
public int TokensDefined => directServer.UiClientContexts.Count;
///
/// Count of connected clients
///
[JsonProperty("clientsConnected")]
public int ClientsConnected => directServer.ConnectedUiClientsCount;
///
/// List of tokens and connected clients for this server
///
[JsonProperty("clients")]
public List Clients => directServer.UiClientContexts
.Select(context => (context, clients: directServer.UiClients.Where(client => client.Value.Token == context.Value.Token.Token).Select(c => c.Value).ToList()))
.Select((clientTuple, i) => new MobileControlDirectClient(clientTuple.clients, clientTuple.context, i, directServer.UserAppUrlPrefix))
.ToList();
///
/// Create an instance of the class.
///
///
public MobileControlDirectServer(MobileControlWebsocketServer server)
{
directServer = server;
}
}
///
/// Represents a MobileControlDirectClient
///
public class MobileControlDirectClient
{
[JsonIgnore]
private readonly UiClientContext context;
[JsonIgnore]
private readonly string Key;
[JsonIgnore]
private readonly int clientNumber;
[JsonIgnore]
private readonly string urlPrefix;
///
/// Client number for this client
///
[JsonProperty("clientNumber")]
public string ClientNumber => $"{clientNumber}";
///
/// Room Key for this client
///
[JsonProperty("roomKey")]
public string RoomKey => context.Token.RoomKey;
///
/// Touchpanel Key, if defined, for this client
///
[JsonProperty("touchpanelKey")]
public string TouchpanelKey => context.Token.TouchpanelKey;
///
/// URL for this client
///
[JsonProperty("url")]
public string Url => $"{urlPrefix}{Key}";
///
/// Token for this client
///
[JsonProperty("token")]
public string Token => Key;
private readonly List clients;
///
/// List of status for all connected UI Clients
///
[JsonProperty("clientStatus")]
public List ClientStatus => clients.Select(c => new ClientStatus(c)).ToList();
///
/// Create an instance of the class.
///
/// List of Websocket Clients
/// Context for the client
/// Index of the client
/// URL prefix for the client
public MobileControlDirectClient(List clients, KeyValuePair context, int index, string urlPrefix)
{
this.context = context.Value;
Key = context.Key;
clientNumber = index;
this.urlPrefix = urlPrefix;
this.clients = clients;
}
}
///
/// Report the status of a UiClient
///
public class ClientStatus
{
private readonly UiClient client;
///
/// True if client is connected
///
public bool Connected => client != null && client.Context.WebSocket.IsAlive;
///
/// Get the time this client has been connected
///
public double Duration => client == null ? 0 : client.ConnectedDuration.TotalSeconds;
///
/// Create an instance of the class for the specified client
///
/// client to report on
public ClientStatus(UiClient client)
{
this.client = client;
}
}
}