syntax = "proto3";

option go_package = "github.com/opencord/device-management-interface/v3/go/dmi";
package dmi;

import "dmi/commons.proto";
import "dmi/hw.proto";
import "google/protobuf/empty.proto";

// Protos for the management of a hardware and it's components

message PhysicalInventoryRequest {
    Uuid device_uuid = 1;
}

message PhysicalInventoryResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        INTERNAL_ERROR = 2;
        DEVICE_UNREACHABLE = 3;
    }
    Status status = 1;
    Reason reason = 2;
    Hardware inventory = 3;
}

message HWComponentInfoGetRequest {
    Uuid device_uuid = 1;
    Uuid component_uuid = 2;
    string component_name = 3;
}

message HWComponentInfoGetResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        UNKNOWN_COMPONENT = 2;
        INTERNAL_ERROR = 3;
        DEVICE_UNREACHABLE = 4;
    }
    Status status = 1;
    Reason reason = 2;
    Component component = 3;
}

message HWComponentInfoSetRequest {
    Uuid device_uuid = 1;
    Uuid component_uuid = 2;
    string component_name = 3;
    ModifiableComponent changes = 4;
}

message HWComponentInfoSetResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        UNKNOWN_COMPONENT = 2;
        INVALID_PARAMS = 3;
        INTERNAL_ERROR = 4;
        DEVICE_UNREACHABLE = 5;
    }
    Status status = 1;
    Reason reason = 2;
}

message StartManagingDeviceResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        // DEVICE_ALREADY_MANAGED is returned when StartManagingDevice is called again for the same name AFTER a previously
        // successful StartManagingDevice operation
        DEVICE_ALREADY_MANAGED = 1;
        // OPERATION_ALREADY_IN_PROGRESS is returned when StartManagingDevice is called again for the same name BEFORE
        // a previous StartManagingDevice operation has completed
        OPERATION_ALREADY_IN_PROGRESS = 2;
        INVALID_PARAMS = 3;
        INTERNAL_ERROR = 4;
    }
    Status status = 1;
    Reason reason = 2;
    Uuid device_uuid = 3;
}

message StopManagingDeviceRequest {
    string name = 1;
}

message StopManagingDeviceResponse {
    // The only case in which an error is expected is if the name of the
    // device to be stopped is not found
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE= 1;
    }
    Status status = 1;
    Reason reason = 2;
}

message ManagedDevicesResponse {
    repeated ModifiableComponent devices = 1;
}

message SetLoggingEndpointRequest {
    Uuid device_uuid = 1;
    string logging_endpoint = 2;
    string logging_protocol = 3;
}

message SetRemoteEndpointResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        INTERNAL_ERROR = 2;
        LOGGING_ENDPOINT_ERROR = 3;
        LOGGING_ENDPOINT_PROTOCOL_ERROR = 4;
        MSGBUS_ENDPOINT_ERROR = 5;
        DEVICE_UNREACHABLE = 6;
    }
    Status status = 1;
    Reason reason = 2;
}

message GetLoggingEndpointResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        INTERNAL_ERROR = 2;
        DEVICE_UNREACHABLE = 3;
    }
    Status status = 1;
    Reason reason = 2;
    string logging_endpoint = 3;
    string logging_protocol = 4;
}

message SetMsgBusEndpointRequest {
    string msgbus_endpoint = 1;
}

message GetMsgBusEndpointResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        INTERNAL_ERROR = 1;
        DEVICE_UNREACHABLE = 2;
    }
    Status status = 1;
    Reason reason = 2;
    string msgbus_endpoint = 3;
}

message EntitiesLogLevel {
    LogLevel logLevel = 1;
    repeated string entities = 2;
}

message SetLogLevelRequest {
    Uuid device_uuid = 1;
    repeated EntitiesLogLevel loglevels = 2;
}

message SetLogLevelResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        INTERNAL_ERROR = 2;
        UNKNOWN_LOG_ENTITY = 3;
        DEVICE_UNREACHABLE = 4;
    }
    Uuid device_uuid = 1;
    Status status = 2;
    Reason reason = 3;
}

message GetLogLevelRequest {
    Uuid device_uuid = 1;
    repeated string entities = 2;
}

message GetLogLevelResponse {
    enum Reason {
        UNDEFINED_REASON = 0;
        UNKNOWN_DEVICE = 1;
        INTERNAL_ERROR = 2;
        UNKNOWN_LOG_ENTITY = 3;
        DEVICE_UNREACHABLE = 4;
    }
    Uuid device_uuid = 1;
    repeated EntitiesLogLevel logLevels = 2;
    Status status = 3;
    Reason reason = 4;
}

message GetLoggableEntitiesRequest {
    Uuid device_uuid = 1;
}

service NativeHWManagementService {
    // Initializes context for a device and sets up required states
    // In the call to StartManagingDevice, the fields of ModifiableComponent which are relevant
    // and their meanings in this context is mentioned below:
    // name = The unique name that needs to be assigned to this hardware;
    // class = COMPONENT_TYPE_UNDEFINED;
    // parent = nil;
    // alias = Optional;
    // asset_id = Optional;
    // uri = IP Address of the Hardware;
    rpc StartManagingDevice(ModifiableComponent) returns(stream StartManagingDeviceResponse);

    // Stop management of a device and clean up any context and caches for that device
    // This rpc can be called at any time, even before the StartManagingDevice operation
    // has completed, and should be able to cleanup.
    rpc StopManagingDevice(StopManagingDeviceRequest) returns(StopManagingDeviceResponse);

    // Returns an object containing a list of devices managed by this entity
    rpc GetManagedDevices(google.protobuf.Empty) returns(ManagedDevicesResponse);

    // Get the HW inventory details of the Device
    rpc GetPhysicalInventory(PhysicalInventoryRequest) returns(stream PhysicalInventoryResponse);

    // Get the details of a particular HW component
    rpc GetHWComponentInfo(HWComponentInfoGetRequest) returns(stream HWComponentInfoGetResponse);

    // Sets the permissible attributes of a HW component
    rpc SetHWComponentInfo(HWComponentInfoSetRequest) returns(HWComponentInfoSetResponse);

    // Sets the location to which logs need to be shipped
    rpc SetLoggingEndpoint(SetLoggingEndpointRequest) returns(SetRemoteEndpointResponse);

    // Gets the configured location to which the logs are being shipped
    rpc GetLoggingEndpoint(HardwareID) returns(GetLoggingEndpointResponse);

    // Sets the location of the Message Bus to which events and metrics are shipped
    rpc SetMsgBusEndpoint(SetMsgBusEndpointRequest) returns(SetRemoteEndpointResponse);

    // Gets the configured location to which the events and metrics are being shipped
    rpc GetMsgBusEndpoint(google.protobuf.Empty) returns(GetMsgBusEndpointResponse);

    // Gets the entities of a device on which log can be configured. A few are expected, like OS, PON Management etc.
    // In general an entity is any item within an hardware system that can emit logs, e.g. service, process, subsystem,
    // interface, package etc.
    rpc GetLoggableEntities(GetLoggableEntitiesRequest) returns(GetLogLevelResponse);

    // Sets the log level of the device, for each given entity to a certain level.
    // If only one EntitiesLogLevel is provided for the device and that request contains only a log level with
    // no entity in the list it's assumed that the caller wants to set that level for all the entities.
    rpc SetLogLevel(SetLogLevelRequest) returns(SetLogLevelResponse);

    // Gets the configured log level for a certain entity on a certain device.
    // If no entity is specified in the request all the entities with their log level should be returned.
    rpc GetLogLevel(GetLogLevelRequest) returns(GetLogLevelResponse);
}
