syntax = "proto3";

package weather_system;
option go_package = "sensor_go/weather_system";

option java_package = "com.weather.monitoring.grpc";
option java_outer_classname = "Weather";

// Messages
// ----------------------------------------------------------------

// 1. Weather Data sent from the sensor (WeatherData)
message WeatherData {
  double temperature_celsius = 1; // Temperature in Celsius (e.g., 25.5)
  double humidity_percent = 2;    // Humidity percentage (e.g., 60.0)
  double pressure_hpa = 3;        // Pressure in Hectopascals (e.g., 1012.3)
  int64 timestamp = 4;            // Unix timestamp of the reading
  string station_id = 5;          // Identifier of the weather station
}

// 2. Calculated Weather Statistics (WeatherStats)
message WeatherStats {
  double avg_temperature = 1;
  double avg_humidity = 2;
  double avg_pressure = 3;
  int64 report_time = 4;

  // Optional field to send alerts within the data stream
  AlertMessage current_alert = 5;
}

// 3. Alert Message (AlertMessage)
message AlertMessage {
  enum AlertType {
    UNKNOWN = 0;

    HIGH_TEMPERATURE = 1;
    LOW_PRESSURE = 2;
    HIGH_HUMIDITY = 3;
    NORMAL = 4;
  }

  AlertType type = 1;
  string message = 2;
  double value = 3;
  int64 timestamp = 4;
}

// 4. Authentication Metadata (AuthMetadata)
// *Note: Token is typically sent via gRPC Metadata, but defined here for completeness*
message AuthMetadata {
  string api_token = 1;
}

// Empty message
message Empty {}

// Services and RPCs
// ----------------------------------------------------------------

// 1. Weather Sensor Service (Go)
// *This service won't act as a server; it's the client for the main RPC.*

// 2. Weather Analytics Service (Python) - The central server
service WeatherAnalyticsService {

  // A. Client Streaming (Required: Receive from Sensor)
  // Sensor streams data; the server (Analytics) returns the final stats.
  // Auth note: Token validation will use gRPC Metadata, not this message field.
  rpc StreamWeatherData(stream WeatherData) returns (WeatherStats);

  // B. Server Streaming (Required: Send to Dashboard)
  // Dashboard requests (with Empty) a continuous stream of reports.
  rpc StreamAnalytics(Empty) returns (stream WeatherStats);

  // C. Unary RPC (Optional Requirement: Retrieve last report)
  // Dashboard manually requests the last stored stats.
  rpc GetLastReport(Empty) returns (WeatherStats);

  // D. Bidirectional Streaming (Academic addition)
  // Allows the server to send immediate alerts and potentially control the sensor.
  rpc ControlSensor(stream AlertMessage) returns (stream WeatherData);
}