use failure::Error;
use isis_ants_api::{AntsTelemetry, DeployStatus, IAntS, KANTSAnt};
use juniper::FieldResult;
use kubos_service::{process_errors, push_err, run};
use std::sync::{Arc, Mutex, RwLock};
#[derive(GraphQLObject)]
pub struct GenericResponse {
pub errors: String,
pub success: bool,
}
#[derive(GraphQLEnum, Clone, Copy)]
pub enum AckCommand {
None,
Noop,
ControlPower,
ConfigureHardware,
TestHardware,
IssueRawCommand,
Arm,
Deploy,
}
#[derive(GraphQLEnum, Eq, PartialEq, Debug)]
pub enum ArmStatus {
Armed,
Disarmed,
}
#[derive(GraphQLEnum)]
pub enum ArmState {
Arm,
Disarm,
}
pub type ArmResponse = GenericResponse;
#[derive(GraphQLEnum, Clone, Copy, Eq, PartialEq, Debug)]
pub enum ConfigureController {
Primary,
Secondary,
}
#[derive(GraphQLObject)]
pub struct ConfigureHardwareResponse {
pub errors: String,
pub success: bool,
pub config: ConfigureController,
}
#[derive(GraphQLEnum, Clone, Eq, PartialEq, Debug)]
pub enum PowerState {
On,
Off,
Reset,
}
pub struct GetPowerResponse {
pub state: PowerState,
pub uptime: u32,
}
graphql_object!(GetPowerResponse: () |&self| {
field state() -> FieldResult<PowerState> {
Ok(self.state.clone())
}
field uptime() -> FieldResult<i32> {
Ok(self.uptime as i32)
}
});
#[derive(GraphQLObject)]
pub struct ControlPowerResponse {
pub errors: String,
pub success: bool,
pub power: PowerState,
}
#[derive(GraphQLEnum, Clone, Debug, PartialEq)]
pub enum DeploymentStatus {
Deployed,
InProgress,
Partial,
Stowed,
Error,
}
pub struct GetDeployResponse {
pub status: DeploymentStatus,
pub details: DeployStatus,
}
graphql_object!(GetDeployResponse: () |&self| {
field status() -> FieldResult<DeploymentStatus> {
Ok(self.status.clone())
}
field sys_burn_active() -> FieldResult<bool> {
Ok(self.details.sys_burn_active)
}
field sys_ignore_deploy() -> FieldResult<bool> {
Ok(self.details.sys_ignore_deploy)
}
field sys_armed() -> FieldResult<bool> {
Ok(self.details.sys_armed)
}
field ant_1_not_deployed() -> FieldResult<bool> {
Ok(self.details.ant_1_not_deployed)
}
field ant_1_stopped_time() -> FieldResult<bool> {
Ok(self.details.ant_1_stopped_time)
}
field ant_1_active() -> FieldResult<bool> {
Ok(self.details.ant_1_active)
}
field ant_2_not_deployed() -> FieldResult<bool> {
Ok(self.details.ant_2_not_deployed)
}
field ant_2_stopped_time() -> FieldResult<bool> {
Ok(self.details.ant_2_stopped_time)
}
field ant_2_active() -> FieldResult<bool> {
Ok(self.details.ant_2_active)
}
field ant_3_not_deployed() -> FieldResult<bool> {
Ok(self.details.ant_3_not_deployed)
}
field ant_3_stopped_time() -> FieldResult<bool> {
Ok(self.details.ant_3_stopped_time)
}
field ant_3_active() -> FieldResult<bool> {
Ok(self.details.ant_3_active)
}
field ant_4_not_deployed() -> FieldResult<bool> {
Ok(self.details.ant_4_not_deployed)
}
field ant_4_stopped_time() -> FieldResult<bool> {
Ok(self.details.ant_4_stopped_time)
}
field ant_4_active() -> FieldResult<bool> {
Ok(self.details.ant_4_active)
}
});
#[derive(GraphQLEnum)]
pub enum DeployType {
All,
Antenna1,
Antenna2,
Antenna3,
Antenna4,
}
pub type DeployResponse = GenericResponse;
pub type NoopResponse = GenericResponse;
#[derive(GraphQLEnum)]
pub enum TestType {
Integration,
Hardware,
}
pub enum TestResults {
Integration(IntegrationTestResults),
Hardware(HardwareTestResults),
}
graphql_union!(TestResults: () where Scalar = <S> |&self| {
instance_resolvers: |&_| {
&IntegrationTestResults => match *self { TestResults::Integration(ref i) => Some(i), _ => None},
&HardwareTestResults => match *self { TestResults::Hardware(ref h) => Some(h), _ => None},
}
});
#[derive(GraphQLObject)]
pub struct IntegrationTestResults {
pub errors: String,
pub success: bool,
pub telemetry_nominal: TelemetryNominal,
pub telemetry_debug: TelemetryDebug,
}
#[derive(GraphQLObject)]
pub struct HardwareTestResults {
pub errors: String,
pub success: bool,
pub data: String,
}
#[derive(GraphQLObject)]
pub struct RawCommandResponse {
pub errors: String,
pub success: bool,
pub response: String,
}
#[derive(GraphQLObject)]
pub struct Telemetry {
pub nominal: TelemetryNominal,
pub debug: TelemetryDebug,
}
#[derive(Debug, Default, PartialEq)]
pub struct TelemetryNominal(pub AntsTelemetry);
graphql_object!(TelemetryNominal: () where Scalar = <S> |&self| {
field raw_temp() -> i32 {
i32::from(self.0.raw_temp)
}
field uptime() -> i32 {
self.0.uptime as i32
}
field sys_burn_active() -> bool {
self.0.deploy_status.sys_burn_active
}
field sys_ignore_deploy() -> bool {
self.0.deploy_status.sys_ignore_deploy
}
field sys_armed() -> bool {
self.0.deploy_status.sys_armed
}
field ant_1_not_deployed() -> bool {
self.0.deploy_status.ant_1_not_deployed
}
field ant_1_stopped_time() -> bool {
self.0.deploy_status.ant_1_stopped_time
}
field ant_1_active() -> bool {
self.0.deploy_status.ant_1_active
}
field ant_2_not_deployed() -> bool {
self.0.deploy_status.ant_2_not_deployed
}
field ant_2_stopped_time() -> bool {
self.0.deploy_status.ant_2_stopped_time
}
field ant_2_active() -> bool {
self.0.deploy_status.ant_2_active
}
field ant_3_not_deployed() -> bool {
self.0.deploy_status.ant_3_not_deployed
}
field ant_3_stopped_time() -> bool {
self.0.deploy_status.ant_3_stopped_time
}
field ant_3_active() -> bool {
self.0.deploy_status.ant_3_active
}
field ant_4_not_deployed() -> bool {
self.0.deploy_status.ant_4_not_deployed
}
field ant_4_stopped_time() -> bool {
self.0.deploy_status.ant_4_stopped_time
}
field ant_4_active() -> bool {
self.0.deploy_status.ant_4_active
}
});
#[derive(Debug, Default, PartialEq)]
pub struct TelemetryDebug {
pub ant1: AntennaStats,
pub ant2: AntennaStats,
pub ant3: AntennaStats,
pub ant4: AntennaStats,
}
#[derive(Debug, Default, PartialEq)]
pub struct AntennaStats {
pub act_count: u8,
pub act_time: u16,
}
pub fn get_stats(
ants_ref: &Arc<Mutex<Box<dyn IAntS>>>,
errors: &Arc<RwLock<Vec<String>>>,
antenna: KANTSAnt,
) -> AntennaStats {
let ants = ants_ref.lock().unwrap();
AntennaStats {
act_count: run!(ants.get_activation_count(antenna.clone()), errors).unwrap_or_default(),
act_time: run!(ants.get_activation_time(antenna), errors).unwrap_or_default(),
}
}
graphql_object!(TelemetryDebug: () where Scalar = <S> |&self| {
field ant_1_activation_count() -> i32 {
i32::from(self.ant1.act_count)
}
field ant_1_activation_time() -> i32 {
i32::from(self.ant1.act_time)
}
field ant_2_activation_count() -> i32 {
i32::from(self.ant2.act_count)
}
field ant_2_activation_time() -> i32 {
i32::from(self.ant2.act_time)
}
field ant_3_activation_count() -> i32 {
i32::from(self.ant3.act_count)
}
field ant_3_activation_time() -> i32 {
i32::from(self.ant3.act_time)
}
field ant_4_activation_count() -> i32 {
i32::from(self.ant4.act_count)
}
field ant_4_activation_time() -> i32 {
i32::from(self.ant4.act_time)
}
});