syntax = "proto3";

package spark;

option java_package = "me.lucko.spark.proto";
option java_outer_classname = "SparkProtos";

message PlatformMetadata {
  Type type = 1;
  string name = 2;
  string version = 3;
  string minecraft_version = 4; // optional
  int32 spark_data_version = 7;
  string brand = 8;
  string spark_version = 9;

  // replaced
  reserved 5, 6;
  reserved "n_cpus", "heap_usage";

  enum Type {
    SERVER = 0;
    CLIENT = 1;
    PROXY = 2;
    APPLICATION = 3;
  }
}

message SystemStatistics {
  Cpu cpu = 1;
  Memory memory = 2;
  map<string, Gc> gc = 3;
  Disk disk = 4;
  Os os = 5;
  Java java = 6;
  int64 uptime = 7;
  map<string, NetInterface> net = 8;
  Jvm jvm = 9;

  message Cpu {
    int32 threads = 1;
    Usage process_usage = 2;
    Usage system_usage = 3;
    string model_name = 4; // optional

    message Usage {
      double last1m = 1;
      double last15m = 2;
    }
  }

  message Memory {
    MemoryPool physical = 1;
    MemoryPool swap = 2;

    message MemoryPool {
      int64 used = 1;
      int64 total = 2;
    }
  }

  message Gc {
    int64 total = 1;
    double avg_time = 2;
    double avg_frequency = 3;
  }

  message Disk {
    int64 used = 1;
    int64 total = 2;
  }

  message Os {
    string arch = 1;
    string name = 2;
    string version = 3;
  }

  message Java {
    string vendor = 1;
    string version = 2;
    string vendor_version = 3;
    string vm_args = 4;
  }

  message Jvm {
    string name = 1;
    string vendor = 2;
    string version = 3;
  }

  message NetInterface {
    RollingAverageValues rx_bytes_per_second = 1;
    RollingAverageValues tx_bytes_per_second = 2;
    RollingAverageValues rx_packets_per_second = 3;
    RollingAverageValues tx_packets_per_second = 4;
  }
}

message PlatformStatistics {
  Memory memory = 1;
  map<string, Gc> gc = 2;
  int64 uptime = 3;
  Tps tps = 4; // optional
  Mspt mspt = 5; // optional
  Ping ping = 6; // optional
  int64 player_count = 7; // optional
  WorldStatistics world = 8; // optional
  OnlineMode online_mode = 9; // optional

  message Memory {
    MemoryUsage heap = 1;
    MemoryUsage non_heap = 2;
    repeated MemoryPool pools = 3;
    RollingAverageValues alloc_bps_last1m = 4;
    RollingAverageValues alloc_bps_last5m = 5;
    RollingAverageValues alloc_bps_last15m = 6;

    message MemoryPool {
      string name = 1;
      MemoryUsage usage = 2;
      MemoryUsage collection_usage = 3;
    }
  }

  message Gc {
    int64 total = 1;
    double avg_time = 2;
    double avg_frequency = 3;
  }

  message Tps {
    double last1m = 1;
    double last5m = 2;
    double last15m = 3;
    int32 game_target_tps = 4;
  }

  message Mspt {
    RollingAverageValues last1m = 1;
    RollingAverageValues last5m = 2;
    int32 game_max_ideal_mspt = 3;
  }

  message Ping {
    RollingAverageValues last15m = 1;
  }

  enum OnlineMode {
    UNKNOWN = 0;
    OFFLINE = 1;
    ONLINE = 2;
  }
}

message WorldStatistics {
  int32 total_entities = 1;
  map<string, int32> entity_counts = 2;
  repeated World worlds = 3;
  repeated GameRule game_rules = 4;
  repeated DataPack data_packs = 5;

  message World {
    string name = 1;
    int32 total_entities = 2;
    repeated Region regions = 3;
  }

  message Region {
    int32 total_entities = 1;
    repeated Chunk chunks = 2;
  }

  message Chunk {
    int32 x = 1;
    int32 z = 2;
    int32 total_entities = 3;
    map<string, int32> entity_counts = 4;
  }

  message GameRule {
    string name = 1;
    string default_value = 2;
    map<string, string> world_values = 3;
  }

  message DataPack {
    string name = 1;
    string description = 2;
    string source = 3;
    bool builtin = 4;
  }
}

message WindowStatistics {
  int32 ticks = 1;
  double cpu_process = 2;
  double cpu_system = 3;
  double tps = 4;
  double mspt_median = 5;
  double mspt_max = 6;

  // world
  int32 players = 7;
  int32 entities = 8;
  int32 tile_entities = 9;
  int32 chunks = 10;

  // approximate wall-clock start/end times
  int64 start_time = 11;
  int64 end_time = 12;
  int32 duration = 13;
}

message RollingAverageValues {
  double mean = 1;
  double max = 2;
  double min = 3;
  double median = 4;
  double percentile95 = 5;
}

message MemoryUsage {
  int64 used = 1;
  int64 committed = 2;
  int64 init = 3;
  int64 max = 4;
}

message DoubleMetricSeries {
  int64 start_timestamp_ms = 1;
  repeated uint32 timestamp_deltas_ms = 2;
  repeated double values = 3;
}

message AveragesMetricSeries {
  int64 start_timestamp_ms = 1;
  repeated uint32 timestamp_deltas_ms = 2;
  repeated RollingAverageValues values = 3;
}

message MemoryUsageMetricSeries {
  int64 start_timestamp_ms = 1;
  repeated uint32 timestamp_deltas_ms = 2;
  repeated MemoryUsage values = 3;
}

message WorldInfoMetricSeries {
  int64 start_timestamp_ms = 1;
  repeated uint32 timestamp_deltas_ms = 2;
  repeated Values values = 3;

  message Values {
    int32 players = 1;
    int32 entities = 2;
    int32 tile_entities = 3;
    int32 chunks = 4;
  }
}

message Metrics {
  DoubleMetricSeries tps = 1;
  AveragesMetricSeries tick_duration = 2;
  DoubleMetricSeries cpu_usage_process = 3;
  DoubleMetricSeries cpu_usage_system = 4;
  MemoryUsageMetricSeries memory_usage_heap = 5;
  MemoryUsageMetricSeries memory_usage_non_heap = 6;
  DoubleMetricSeries memory_allocation = 7;
  WorldInfoMetricSeries world_info = 8;
  AveragesMetricSeries player_ping = 9;
}

message CommandSenderMetadata {
  Type type = 1;
  string name = 2;
  string unique_id = 3;

  enum Type {
    OTHER = 0;
    PLAYER = 1;
  }
}

message PluginOrModMetadata {
  string name = 1;
  string version = 2;
  string author = 3;
  string description = 4;
  bool builtin = 5;
}

message HealthData {
  HealthMetadata metadata = 1;
  map<int32, WindowStatistics> time_window_statistics = 2;
  SocketChannelInfo channel_info = 3;
}

message HealthMetadata {
  CommandSenderMetadata creator = 1;
  PlatformMetadata platform_metadata = 2;
  PlatformStatistics platform_statistics = 3;
  SystemStatistics system_statistics = 4;
  int64 generated_time = 5;
  map<string, string> server_configurations = 6;
  map<string, PluginOrModMetadata> sources = 7;
  map<string, string> extra_platform_metadata = 8;
  Metrics metrics = 9;
}

message SocketChannelInfo {
  string channel_id = 1;
  bytes public_key = 2;
}
