1use std::any::Any;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use log::{info, error, debug, warn};
5use async_trait::async_trait;
6use sharing::utils::ConfigEnv;
7use crate::service::{Service, WebSocketWrite};
8
9pub const BASE_VERSION: &str = "1.0.0";
11
12#[derive(Deserialize, Serialize, Debug, Clone)]
14#[serde(rename_all = "UPPERCASE")]
15pub enum BaseAction {
16 Check,
18 Print { action: String },
20 Ping,
22 Unknown,
24}
25
26impl From<&str> for BaseAction {
27 fn from(action: &str) -> Self {
29 match action {
30 "CHECK" => BaseAction::Check,
31 "PRINT" => BaseAction::Print { action: "print".to_string() },
32 "PING" => BaseAction::Ping,
33 _ => BaseAction::Unknown,
34 }
35 }
36}
37
38#[derive(Clone)]
40pub struct BaseService;
41
42impl BaseService {
43 pub fn new() -> Self {
45 info!("BaseService initialized (version: {})", BASE_VERSION);
46 BaseService
47 }
48}
49
50#[async_trait]
52impl Service for BaseService {
53 async fn run(&self, action: Value, _write: WebSocketWrite) -> (i32, String) {
55 let action_str = action.get("ACTION").and_then(|v| v.as_str()).unwrap_or("UNKNOWN");
56 if action_str == "PING" {
59 debug!("BaseService: Running action: {:?}", action);
60 } else {
61 info!("BaseService: Running action: {:?}", action);
62 }
63 match action_str {
64 "CHECK" => {
65 if let Some(place_id) = action.get("place_id").and_then(|v| v.as_i64()) {
73 let mut config = ConfigEnv::load();
74 let was = config.place_id;
75 match config.set_place_id(place_id) {
76 Ok(()) => {
77 if was.is_none() {
78 info!(
79 "BaseService: CHECK bound this TPV to place_id={place_id}"
80 );
81 } else {
82 debug!(
83 "BaseService: CHECK reaffirms place_id={place_id}"
84 );
85 }
86 }
87 Err(e) => {
88 warn!("BaseService: CHECK rejected — {e}");
89 return (1, format!("place_id mismatch: {e}"));
90 }
91 }
92 }
93 info!("BaseService: Performing check action");
94 (0, "check ok".to_string())
95 }
96 "PING" => {
97 debug!("BaseService: Performing ping action");
98 (0, "pong".to_string()) }
100 _ => {
101 error!("BaseService: Unknown action");
102 (1, "unknown action".to_string())
103 }
104 }
105 }
106
107 fn as_any(&self) -> &dyn Any {
109 self
110 }
111
112 fn stop_service(&self) {
114 info!("BaseService: Stopping service");
115 }
116
117 fn get_version(&self) -> String {
119 BASE_VERSION.to_string()
120 }
121}
122
123impl Default for BaseAction {
124 fn default() -> Self {
126 BaseAction::Unknown
127 }
128}