/********************************************************************************
 * Copyright (c) 2022 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Apache License 2.0 which is available at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * SPDX-License-Identifier: Apache-2.0
 ********************************************************************************/

 syntax = "proto3";

 // I added V1 as in databroker. Is this good practice?
 package kuksa.val.v1;
 import "google/protobuf/timestamp.proto";
 
 option go_package = "kuksa/val/v1";
 
 // Describes a VSS entry
 // When requesting an entry, the amount of information returned can
 // be controlled by specifying either a `View` or a set of `Field`s.
 message DataEntry {
   // Defines the full VSS path of the entry.
   string path = 1;  // [field: FIELD_PATH]
 
   // The value (datapoint)
   Datapoint value = 2;  // [field: FIELD_VALUE]
 
   // Actuator target (only used if the entry is an actuator)
   Datapoint actuator_target = 3;  // [field: FIELD_ACTUATOR_TARGET]
 
   // Metadata for this entry
   Metadata metadata = 10;  // [field: FIELD_METADATA]
 }
 
 message Datapoint {
   google.protobuf.Timestamp timestamp = 1;
 
   oneof value {
     string string            = 11;
     bool bool                = 12;
     sint32 int32             = 13;
     sint64 int64             = 14;
     uint32 uint32            = 15;
     uint64 uint64            = 16;
     float float              = 17;
     double double            = 18;
     StringArray string_array = 21;
     BoolArray bool_array     = 22;
     Int32Array int32_array   = 23;
     Int64Array int64_array   = 24;
     Uint32Array uint32_array = 25;
     Uint64Array uint64_array = 26;
     FloatArray float_array   = 27;
     DoubleArray double_array = 28;
   }
 }
 
 message Metadata {
   // Data type
   // The VSS data type of the entry (i.e. the value, min, max etc).
   //
   // NOTE: protobuf doesn't have int8, int16, uint8 or uint16 which means
   // that these values must be serialized as int32 and uint32 respectively.
   DataType data_type = 11;  // [field: FIELD_METADATA_DATA_TYPE]
 
   // Entry type
   EntryType entry_type = 12;  // [field: FIELD_METADATA_ENTRY_TYPE]
 
   // Description
   // Describes the meaning and content of the entry.
   optional string description = 13;  // [field: FIELD_METADATA_DESCRIPTION]
 
   // Comment [optional]
   // A comment can be used to provide additional informal information
   // on a entry.
   optional string comment = 14;  // [field: FIELD_METADATA_COMMENT]
 
   // Deprecation [optional]
   // Whether this entry is deprecated. Can contain recommendations of what
   // to use instead.
   optional string deprecation = 15;  // [field: FIELD_METADATA_DEPRECATION]
 
   // Unit [optional]
   // The unit of measurement
   optional string unit = 16;  // [field: FIELD_METADATA_UNIT]
 
   // Value restrictions [optional]
   // Restrict which values are allowed.
   // Only restrictions matching the DataType {datatype} above are valid.
   ValueRestriction value_restriction = 17;  // [field: FIELD_METADATA_VALUE_RESTRICTION]
 
   // Entry type specific metadata
   oneof entry_specific {
     Actuator actuator   = 20;  // [field: FIELD_METADATA_ACTUATOR]
     Sensor sensor       = 30;  // [field: FIELD_METADATA_SENSOR]
     Attribute attribute = 40;  // [field: FIELD_METADATA_ATTRIBUTE]
   }
 }
 
 ///////////////////////
 // Actuator specific fields
 message Actuator {
   // Nothing for now
 }
 
 ////////////////////////
 // Sensor specific
 message Sensor {
   // Nothing for now
 }
 
 ////////////////////////
 // Attribute specific
 message Attribute {
   // Nothing for now.
 }
 
 // Value restriction
 //
 // One ValueRestriction{type} for each type, since
 // they don't make sense unless the types match
 //
 message ValueRestriction {
   oneof type {
     ValueRestrictionString string = 21;
     // For signed VSS integers
     ValueRestrictionInt signed = 22;
     // For unsigned VSS integers
     ValueRestrictionUint unsigned = 23;
     // For floating point VSS values (float and double)
     ValueRestrictionFloat floating_point = 24;
   }
 }
 
 message ValueRestrictionInt {
   optional sint64 min            = 1;
   optional sint64 max            = 2;
   repeated sint64 allowed_values = 3;
 }
 
 message ValueRestrictionUint {
   optional uint64 min            = 1;
   optional uint64 max            = 2;
   repeated uint64 allowed_values = 3;
 }
 
 message ValueRestrictionFloat {
   optional double min = 1;
   optional double max = 2;
 
   // allowed for doubles/floats not recommended
   repeated double allowed_values = 3;
 }
 
 // min, max doesn't make much sense for a string
 message ValueRestrictionString {
   repeated string allowed_values = 3;
 }
 
 // VSS Data type of a signal
 //
 // Protobuf doesn't support int8, int16, uint8 or uint16.
 // These are mapped to int32 and uint32 respectively.
 //
 enum DataType {
   DATA_TYPE_UNSPECIFIED     = 0;
   DATA_TYPE_STRING          = 1;
   DATA_TYPE_BOOLEAN         = 2;
   DATA_TYPE_INT8            = 3;
   DATA_TYPE_INT16           = 4;
   DATA_TYPE_INT32           = 5;
   DATA_TYPE_INT64           = 6;
   DATA_TYPE_UINT8           = 7;
   DATA_TYPE_UINT16          = 8;
   DATA_TYPE_UINT32          = 9;
   DATA_TYPE_UINT64          = 10;
   DATA_TYPE_FLOAT           = 11;
   DATA_TYPE_DOUBLE          = 12;
   DATA_TYPE_TIMESTAMP       = 13;
   DATA_TYPE_STRING_ARRAY    = 20;
   DATA_TYPE_BOOLEAN_ARRAY   = 21;
   DATA_TYPE_INT8_ARRAY      = 22;
   DATA_TYPE_INT16_ARRAY     = 23;
   DATA_TYPE_INT32_ARRAY     = 24;
   DATA_TYPE_INT64_ARRAY     = 25;
   DATA_TYPE_UINT8_ARRAY     = 26;
   DATA_TYPE_UINT16_ARRAY    = 27;
   DATA_TYPE_UINT32_ARRAY    = 28;
   DATA_TYPE_UINT64_ARRAY    = 29;
   DATA_TYPE_FLOAT_ARRAY     = 30;
   DATA_TYPE_DOUBLE_ARRAY    = 31;
   DATA_TYPE_TIMESTAMP_ARRAY = 32;
 }
 
 // Entry type
 enum EntryType {
   ENTRY_TYPE_UNSPECIFIED = 0;
   ENTRY_TYPE_ATTRIBUTE   = 1;
   ENTRY_TYPE_SENSOR      = 2;
   ENTRY_TYPE_ACTUATOR    = 3;
 }
 
 // A `View` specifies a set of fields which should
 // be populated in a `DataEntry` (in a response message)
 enum View {
   VIEW_UNSPECIFIED   = 0;   // Unspecified. Equivalent to VIEW_CURRENT_VALUE unless `fields` are explicitly set.
   VIEW_CURRENT_VALUE = 1;   // Populate DataEntry with value.
   VIEW_TARGET_VALUE  = 2;   // Populate DataEntry with actuator target.
   VIEW_METADATA      = 3;   // Populate DataEntry with metadata.
   VIEW_FIELDS        = 10;  // Populate DataEntry only with requested fields.
   VIEW_ALL           = 20;  // Populate DataEntry with everything.
 }
 
 // A `Field` corresponds to a specific field of a `DataEntry`.
 //
 // It can be used to:
 //   * populate only specific fields of a `DataEntry` response.
 //   * specify which fields of a `DataEntry` should be set as
 //     part of a `Set` request.
 //   * subscribe to only specific fields of a data entry.
 //   * convey which fields of an updated `DataEntry` have changed.
 enum Field {
   FIELD_UNSPECIFIED                = 0;   // "*" i.e. everything
   FIELD_PATH                       = 1;   // path
   FIELD_VALUE                      = 2;   // value
   FIELD_ACTUATOR_TARGET            = 3;   // actuator_target
   FIELD_METADATA                   = 10;  // metadata.*
   FIELD_METADATA_DATA_TYPE         = 11;  // metadata.data_type
   FIELD_METADATA_DESCRIPTION       = 12;  // metadata.description
   FIELD_METADATA_ENTRY_TYPE        = 13;  // metadata.entry_type
   FIELD_METADATA_COMMENT           = 14;  // metadata.comment
   FIELD_METADATA_DEPRECATION       = 15;  // metadata.deprecation
   FIELD_METADATA_UNIT              = 16;  // metadata.unit
   FIELD_METADATA_VALUE_RESTRICTION = 17;  // metadata.value_restriction.*
   FIELD_METADATA_ACTUATOR          = 20;  // metadata.actuator.*
   FIELD_METADATA_SENSOR            = 30;  // metadata.sensor.*
   FIELD_METADATA_ATTRIBUTE         = 40;  // metadata.attribute.*
 }
 
 // Error response shall be an HTTP-like code.
 // Should follow https://www.w3.org/TR/viss2-transport/#status-codes.
 message Error {
   uint32 code    = 1;
   string reason  = 2;
   string message = 3;
 }
 
 // Used in get/set requests to report errors for specific entries
 message DataEntryError {
   string path = 1;  // vss path
   Error error = 2;
 }
 
 message StringArray {
   repeated string values = 1;
 }
 
 message BoolArray {
   repeated bool values = 1;
 }
 
 message Int32Array {
   repeated sint32 values = 1;
 }
 
 message Int64Array {
   repeated sint64 values = 1;
 }
 
 message Uint32Array {
   repeated uint32 values = 1;
 }
 
 message Uint64Array {
   repeated uint64 values = 1;
 }
 
 message FloatArray {
   repeated float values = 1;
 }
 
 message DoubleArray {
   repeated double values = 1;
 }
 