/**
 * Copyright © 2016-2026 The Thingsboard Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
syntax = "proto3";

import "google/protobuf/any.proto";


option java_package = "org.thingsboard.server.gen.transport.mqtt";
option java_outer_classname = "SparkplugBProto";


enum DataType {
  // Indexes of Data Types

  // Unknown placeholder for future expansion.
  Unknown         = 0;

  // Basic Types
  Int8            = 1;
  Int16           = 2;
  Int32           = 3;
  Int64           = 4;
  UInt8           = 5;
  UInt16          = 6;
  UInt32          = 7;
  UInt64          = 8;
  Float           = 9;
  Double          = 10;
  Boolean         = 11;
  String          = 12;
  DateTime        = 13;
  Text            = 14;

  // Additional Metric Types
  UUID            = 15;
  DataSet         = 16;
  Bytes           = 17;
  File            = 18;
  Template        = 19;

  // Additional PropertyValue Types
  PropertySet     = 20;
  PropertySetList = 21;

  // Array Types
  Int8Array = 22;
  Int16Array = 23;
  Int32Array = 24;
  Int64Array = 25;
  UInt8Array = 26;
  UInt16Array = 27;
  UInt32Array = 28;
  UInt64Array = 29;
  FloatArray = 30;
  DoubleArray = 31;
  BooleanArray = 32;
  StringArray = 33;
  DateTimeArray = 34;
}

message Payload {

  message Template {

    message Parameter {
      optional string name = 1;
      optional uint32 type = 2;

      oneof value {
        uint32 int_value = 3;
        uint64 long_value = 4;
        float  float_value = 5;
        double double_value = 6;
        bool   boolean_value = 7;
        string string_value = 8;
        ParameterValueExtension extension_value = 9;
      }

      message ParameterValueExtension {
        google.protobuf.Any extensions = 1;
      }
    }

    optional string version = 1;          // The version of the Template to prevent mismatches
    repeated Metric metrics = 2;          // Each metric is the name of the metric and the datatype of the member but does not contain a value
    repeated Parameter parameters = 3;
    optional string template_ref = 4;     // Reference to a template if this is extending a Template or an instance - must exist if an instance
    optional bool is_definition = 5;
    google.protobuf.Any extensions = 6;
  }

  message DataSet {

    message DataSetValue {

      oneof value {
        uint32 int_value = 1;
        uint64 long_value = 2;
        float  float_value = 3;
        double double_value = 4;
        bool   boolean_value = 5;
        string string_value = 6;
        DataSetValueExtension extension_value = 7;
      }

      message DataSetValueExtension {
        google.protobuf.Any extensions = 1;
      }
    }

    message Row {
      repeated DataSetValue elements = 1;
      google.protobuf.Any extensions = 2;   // For third party extensions
    }

    optional uint64   num_of_columns = 1;
    repeated string   columns = 2;
    repeated uint32   types = 3;
    repeated Row      rows = 4;
    google.protobuf.Any extensions = 5;   // For third party extensions
  }

  message PropertyValue {

    optional uint32     type = 1;
    optional bool       is_null = 2;

    oneof value {
      uint32          int_value = 3;
      uint64          long_value = 4;
      float            float_value = 5;
      double          double_value = 6;
      bool            boolean_value = 7;
      string          string_value = 8;
      PropertySet     propertyset_value = 9;
      PropertySetList propertysets_value = 10;      // List of Property Values
      PropertyValueExtension extension_value = 11;
    }

    message PropertyValueExtension {
      google.protobuf.Any extensions = 1;
    }
  }

  message PropertySet {
    repeated string        keys = 1;         // Names of the properties
    repeated PropertyValue values = 2;
    google.protobuf.Any extensions = 3;
  }

  message PropertySetList {
    repeated PropertySet propertyset = 1;
    google.protobuf.Any extensions = 2;
  }

  message MetaData {
    // Bytes specific metadata
    optional bool   is_multi_part = 1;

    // General metadata
    optional string content_type = 2;    // Content/Media type
    optional uint64 size = 3;            // File size, String size, Multi-part size, etc
    optional uint64 seq = 4;             // Sequence number for multi-part messages

    // File metadata
    optional string file_name = 5;        // File name
    optional string file_type = 6;        // File type (i.e. xml, json, txt, cpp, etc)
    optional string md5 = 7;             // md5 of data

    // Catchalls and future expansion
    optional string description = 8;     // Could be anything such as json or xml of custom properties
    google.protobuf.Any extensions = 9;
  }

  message Metric {

    optional string   name = 1;            // Metric name - should only be included on birth
    optional uint64   alias = 2;           // Metric alias - tied to name on birth and included in all later DATA messages
    optional uint64   timestamp = 3;       // Timestamp associated with data acquisition time
    optional uint32   datatype = 4;        // DataType of the metric/tag value
    optional bool     is_historical = 5;   // If this is historical data and should not update real time tag
    optional bool     is_transient = 6;    // Tells consuming clients such as MQTT Engine to not store this as a tag
    optional bool     is_null = 7;         // If this is null - explicitly say so rather than using -1, false, etc for some datatypes.
    optional MetaData metadata = 8;        // Metadata for the payload
    optional PropertySet properties = 9;

    oneof value {
      uint32   int_value = 10;
      uint64   long_value = 11;
      float    float_value = 12;
      double   double_value = 13;
      bool     boolean_value = 14;
      string   string_value = 15;
      bytes    bytes_value = 16;       // Bytes, File
      DataSet  dataset_value = 17;
      Template template_value = 18;
      MetricValueExtension extension_value = 19;
    }

    message MetricValueExtension {
      google.protobuf.Any extensions = 1;
    }
  }

  optional uint64   timestamp = 1;  // Timestamp at message sending time
  repeated Metric   metrics = 2;    // Repeated forever - no limit in Google Protobufs
  optional uint64   seq = 3;        // Sequence number
  optional string   uuid = 4;       // UUID to track message type in terms of schema definitions
  optional bytes    body = 5;       // To optionally bypass the whole definition above
  google.protobuf.Any extensions = 6;
}