/*
 * Top-level Voltha API definition
 *
 * For details, see individual definition files.
 */

syntax = "proto3";

option go_package = "github.com/opencord/voltha-protos/v5/go/voltha";

package voltha;

import "google/api/annotations.proto";
import "google/protobuf/empty.proto";

import public "voltha_protos/common.proto";
import "voltha_protos/health.proto";
import "voltha_protos/logical_device.proto";
import "voltha_protos/device.proto";
import "voltha_protos/adapter.proto";
import "voltha_protos/openflow_13.proto";
import "voltha_protos/events.proto";
import "voltha_protos/extensions.proto";
import "voltha_protos/voip_system_profile.proto";
import "voltha_protos/voip_user_profile.proto";

import "voltha_protos/omci_mib_db.proto";
import "voltha_protos/omci_alarm_db.proto";
import "voltha_protos/omci_test.proto";

option java_package = "org.opencord.voltha";
option java_outer_classname = "VolthaProtos";
option csharp_namespace = "Opencord.Voltha.Voltha";

// CoreInstance represents a core instance.  It is data held in memory when a core
// is running.  This data is not persistent.
message CoreInstance {

    string instance_id = 1;

    health.HealthStatus health = 2;

}

message CoreInstances {
    repeated CoreInstance items = 1;
}


// Voltha represents the Voltha cluster data.  Each Core instance will hold a subset of
// the entire cluster. However, some items (e.g. adapters) will be held by all cores
// for better performance
message Voltha {

    string version = 1 ;

    repeated adapter.Adapter adapters = 2;

    repeated logical_device.LogicalDevice logical_devices = 3;

    repeated device.Device devices = 4;

    repeated device.DeviceType device_types = 5;

    reserved 6;
    // device_groups is not used
    // repeated DeviceGroup device_groups = 6;

    repeated event.EventFilter event_filters = 7;

    repeated
        omci.MibDeviceData omci_mib_database = 28;

    repeated
        omci.AlarmDeviceData omci_alarm_database = 29;
}

/*
 * Voltha APIs
 *
 */
service VolthaService {
    // Get high level information on the Voltha cluster
    rpc GetVoltha(google.protobuf.Empty) returns(Voltha) {
        option (google.api.http) = {
            get: "/api/v1"
        };
    }

    // List all Voltha cluster core instances
    rpc ListCoreInstances(google.protobuf.Empty) returns(CoreInstances) {
        option (google.api.http) = {
            get: "/api/v1/instances"
        };
    }

    // Get details on a Voltha cluster instance
    rpc GetCoreInstance(common.ID) returns(CoreInstance) {
        option (google.api.http) = {
            get: "/api/v1/instances/{id}"
        };
    }

    // List all active adapters (plugins) in the Voltha cluster
    rpc ListAdapters(google.protobuf.Empty) returns(adapter.Adapters) {
        option (google.api.http) = {
            get: "/api/v1/adapters"
        };
    }


    // List all logical devices managed by the Voltha cluster
    rpc ListLogicalDevices(google.protobuf.Empty) returns(logical_device.LogicalDevices) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices"
        };
    }

    // Get additional information on a given logical device
    rpc GetLogicalDevice(common.ID) returns(logical_device.LogicalDevice) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}"
        };
    }

    // List ports of a logical device
    rpc ListLogicalDevicePorts(common.ID) returns(logical_device.LogicalPorts) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}/ports"
        };
    }

    // Gets a logical device port
    rpc GetLogicalDevicePort(logical_device.LogicalPortId) returns(logical_device.LogicalPort) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}/ports/{port_id}"
        };
    }

    // Enables a logical device port
    rpc EnableLogicalDevicePort(logical_device.LogicalPortId) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/logical_devices/{id}/ports/{port_id}/enable"
        };
    }

    // Disables a logical device port
    rpc DisableLogicalDevicePort(logical_device.LogicalPortId) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/logical_devices/{id}/ports/{port_id}/disable"
        };
    }

    // List all flows of a logical device
    rpc ListLogicalDeviceFlows(common.ID) returns(openflow_13.Flows) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}/flows"
        };
    }

    // Update flow table for logical device
    rpc UpdateLogicalDeviceFlowTable(openflow_13.FlowTableUpdate)
            returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/logical_devices/{id}/flows"
            body: "*"
        };
    }

    // Update meter table for logical device
    rpc UpdateLogicalDeviceMeterTable(openflow_13.MeterModUpdate)
            returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/logical_devices/{id}/meters"
            body: "*"
        };
    }

    // List all meters of a logical device
    rpc ListLogicalDeviceMeters(common.ID) returns (openflow_13.Meters) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}/meters"
        };
    }

    // List all flow groups of a logical device
    rpc ListLogicalDeviceFlowGroups(common.ID) returns(openflow_13.FlowGroups) {
        option (google.api.http) = {
            get: "/api/v1/logical_devices/{id}/flow_groups"
        };
    }

    // Update group table for device
    rpc UpdateLogicalDeviceFlowGroupTable(openflow_13.FlowGroupTableUpdate)
            returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/logical_devices/{id}/flow_groups"
            body: "*"
        };
    }

    // List all physical devices controlled by the Voltha cluster
    rpc ListDevices(google.protobuf.Empty) returns(device.Devices) {
        option (google.api.http) = {
            get: "/api/v1/devices"
        };
    }

    // List all physical devices IDs controlled by the Voltha cluster
    rpc ListDeviceIds(google.protobuf.Empty) returns(common.IDs) {
        option (google.api.http) = {
            get: "/api/v1/deviceids"
        };
    }

    // Request to a voltha Core to reconcile a set of devices based on their IDs
    rpc ReconcileDevices(common.IDs) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/deviceids"
            body: "*"
        };
    }

    // Get more information on a given physical device
    rpc GetDevice(common.ID) returns(device.Device) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}"
        };
    }

    // Pre-provision a new physical device
    rpc CreateDevice(device.Device) returns(device.Device) {
        option (google.api.http) = {
            post: "/api/v1/devices"
            body: "*"
        };
    }

    // Enable a device.  If the device was in pre-provisioned state then it
    // will transition to ENABLED state.  If it was is DISABLED state then it
    // will transition to ENABLED state as well.
    rpc EnableDevice(common.ID) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/enable"
        };
    }

    // Disable a device
    rpc DisableDevice(common.ID) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/disable"
        };
    }

    // Reboot a device
    rpc RebootDevice(common.ID) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/reboot"
        };
    }

    // Delete a device
    rpc DeleteDevice (common.ID) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/devices/{id}/delete"
        };
    }

    // Forcefully delete a device
    rpc ForceDeleteDevice (common.ID) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/devices/{id}/force_delete"
        };
    }

    // Request an image download to the standby partition
    // of a device.
    // Note that the call is expected to be non-blocking.
    rpc DownloadImage(device.ImageDownload) returns(common.OperationResp) {
        option deprecated = true;
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/image_downloads/{name}"
            body: "*"
        };
    }

    // Get image download status on a device
    // The request retrieves progress on device and updates db record
    // Deprecated in voltha 2.8, will be removed
    rpc GetImageDownloadStatus(device.ImageDownload) returns(device.ImageDownload) {
        option deprecated = true;
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/image_downloads/{name}/status"
        };
    }

    // Get image download db record
    // Deprecated in voltha 2.8, will be removed
    rpc GetImageDownload(device.ImageDownload) returns(device.ImageDownload) {
        option deprecated = true;
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/image_downloads/{name}"
        };
    }

    // List image download db records for a given device
    // Deprecated in voltha 2.8, will be removed
    rpc ListImageDownloads(common.ID) returns(device.ImageDownloads) {
        option deprecated = true;
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/image_downloads"
        };
    }

    // Cancel an existing image download process on a device
    // Deprecated in voltha 2.8, will be removed
    rpc CancelImageDownload(device.ImageDownload) returns(common.OperationResp) {
        option deprecated = true;
        option (google.api.http) = {
            delete: "/api/v1/devices/{id}/image_downloads/{name}"
        };
    }

    // Activate the specified image at a standby partition
    // to active partition.
    // Depending on the device implementation, this call
    // may or may not cause device reboot.
    // If no reboot, then a reboot is required to make the
    // activated image running on device
    // Note that the call is expected to be non-blocking.
    // Deprecated in voltha 2.8, will be removed
    rpc ActivateImageUpdate(device.ImageDownload) returns(common.OperationResp) {
        option deprecated = true;
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/image_downloads/{name}/image_update"
            body: "*"
        };
    }

    // Revert the specified image at standby partition
    // to active partition, and revert to previous image
    // Depending on the device implementation, this call
    // may or may not cause device reboot.
    // If no reboot, then a reboot is required to make the
    // previous image running on device
    // Note that the call is expected to be non-blocking.
    // Deprecated in voltha 2.8, will be removed
    rpc RevertImageUpdate(device.ImageDownload) returns(common.OperationResp) {
        option deprecated = true;
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/image_downloads/{name}/image_revert"
            body: "*"
        };
    }

    // Downloads a certain image to the standby partition of the devices
    // Note that the call is expected to be non-blocking.
    rpc DownloadImageToDevice (device.DeviceImageDownloadRequest) returns (device.DeviceImageResponse) {
        option (google.api.http) = {
            get: "/api/v1/devices/images/download_images"
        };
    }

    // Get image status on a number of devices devices
    // Polled from northbound systems to get state of download/activate/commit
    rpc GetImageStatus (device.DeviceImageRequest) returns (device.DeviceImageResponse) {
        option (google.api.http) = {
            get: "/api/v1/devices/images/images_status"
        };
    }

    // Aborts the upgrade of an image on a device
    // To be used carefully, stops any further operations for the Image on the given devices
    // Might also stop if possible existing work, but no guarantees are given,
    // depends on implementation and procedure status.
    rpc AbortImageUpgradeToDevice (device.DeviceImageRequest) returns (device.DeviceImageResponse) {
        option (google.api.http) = {
            get: "/api/v1/devices/images/abort_upgrade_images"
        };
    }

    // Get Both Active and Standby image for a given device
    rpc GetOnuImages (common.ID) returns (device.OnuImages) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/onu_images"
        };
    }

    // Activate the specified image from a standby partition
    // to active partition.
    // Depending on the device implementation, this call
    // may or may not cause device reboot.
    // If no reboot, then a reboot is required to make the
    // activated image running on device
    // Note that the call is expected to be non-blocking.
    rpc ActivateImage (device.DeviceImageRequest) returns (device.DeviceImageResponse) {
        option (google.api.http) = {
            post: "/api/v1/devices/images/activate_images"
            body: "*"
        };
    }

    // Commit the specified image to be default.
    // Depending on the device implementation, this call
    // may or may not cause device reboot.
    // If no reboot, then a reboot is required to make the
    // activated image running on device upon next reboot
    // Note that the call is expected to be non-blocking.
    rpc CommitImage (device.DeviceImageRequest) returns (device.DeviceImageResponse) {
        option (google.api.http) = {
            post: "/api/v1/devices/images/commit_images"
            body: "*"
        };
    }

    // List ports of a device
    rpc ListDevicePorts (common.ID) returns (device.Ports) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/ports"
        };
    }

    // List pm config of a device
    rpc ListDevicePmConfigs (common.ID) returns (device.PmConfigs) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/pm_configs"
        };
    }

    // Update the pm config of a device
    rpc UpdateDevicePmConfigs(device.PmConfigs) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/pm_configs"
            body: "*"
        };
    }

    // List all flows of a device
    rpc ListDeviceFlows(common.ID) returns(openflow_13.Flows) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/flows"
        };
    }

    // List all flow groups of a device
    rpc ListDeviceFlowGroups(common.ID) returns(openflow_13.FlowGroups) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/flow_groups"
        };
    }

    // List device types known to Voltha
    rpc ListDeviceTypes(google.protobuf.Empty) returns(device.DeviceTypes) {
        option (google.api.http) = {
            get: "/api/v1/device_types"
        };
    }

    // Get additional information on a device type
    rpc GetDeviceType(common.ID) returns(device.DeviceType) {
        option (google.api.http) = {
            get: "/api/v1/device_types/{id}"
        };
    }

    // Stream control packets to the dataplane
    rpc StreamPacketsOut(stream openflow_13.PacketOut)
        returns(google.protobuf.Empty) {
        // This does not have an HTTP representation
    }

    // Receive control packet stream
    rpc ReceivePacketsIn(google.protobuf.Empty)
        returns(stream openflow_13.PacketIn) {
        // This does not have an HTTP representation
    }

    rpc ReceiveChangeEvents(google.protobuf.Empty)
        returns(stream openflow_13.ChangeEvent) {
        // This does not have an HTTP representation
    }

    rpc CreateEventFilter(event.EventFilter) returns(event.EventFilter) {
        option (google.api.http) = {
            post: "/api/v1/event_filters"
            body: "*"
        };
    }

    // Get all filters present for a device
    rpc GetEventFilter(common.ID) returns(event.EventFilters) {
        option (google.api.http) = {
            get: "/api/v1/event_filters/{id}"
        };
    }

    rpc UpdateEventFilter(event.EventFilter) returns(event.EventFilter) {
        option (google.api.http) = {
            put: "/api/v1/event_filters/{id}"
            body: "*"
        };
    }

    rpc DeleteEventFilter(event.EventFilter) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/event_filters/{id}"
        };
    }

    // Get all the filters present
    rpc ListEventFilters(google.protobuf.Empty) returns(event.EventFilters) {
        option (google.api.http) = {
            get: "/api/v1/event_filters"
        };
    }

    rpc GetImages(common.ID) returns(device.Images) {
        option (google.api.http) = {
            get: "/api/v1/devices/{id}/images"
        };
    }

    rpc SelfTest(common.ID) returns(device.SelfTestResponse) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/self_test"
        };
    }

    // OpenOMCI MIB information
    rpc GetMibDeviceData(common.ID) returns(omci.MibDeviceData) {
        option (google.api.http) = {
            get: "/api/v1/openomci/{id}/mib"
        };
    }

    // OpenOMCI ALARM information
    rpc GetAlarmDeviceData(common.ID) returns(omci.AlarmDeviceData) {
        option (google.api.http) = {
            get: "/api/v1/openomci/{id}/alarm"
        };
    }

    // Simulate an Alarm
    rpc SimulateAlarm(device.SimulateAlarmRequest) returns(common.OperationResp) {
        option (google.api.http) = {
            post: "/api/v1/devices/{id}/simulate_larm"
            body: "*"
        };
    }

    rpc EnablePort(device.Port) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/v1/EnablePort"
            body: "*"
        };
    }
    rpc DisablePort(device.Port) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/v1/DisablePort"
            body: "*"
        };
    }
    rpc GetExtValue(extension.ValueSpecifier) returns(extension.ReturnValues) {
        option (google.api.http) = {
            get: "/api/v1/GetExtValue"
        };
    }
    rpc SetExtValue(extension.ValueSet) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            get: "/api/v1/SetExtValue"
        };
    }

    // omci start and stop cli implementation
    rpc StartOmciTestAction(omci.OmciTestRequest) returns(omci.TestResponse) {
        option (google.api.http) = {
            post: "/api/v1/start_omci_test"
            body: "*"
        };
    }

    // Saves or updates system wide configuration into voltha KV
    rpc PutVoipSystemProfile(voip_system_profile.VoipSystemProfileRequest) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/voip_system_profile"
            body: "*"
        };
    }

    // Deletes the given profile from voltha KV
    rpc DeleteVoipSystemProfile(common.Key) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/voip_system_profile/{key}/delete"
        };
    }

    // Saves or updates a profile (VOIP) into voltha KV
    rpc PutVoipUserProfile(voip_user_profile.VoipUserProfileRequest) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/voip_user_profile"
            body: "*"
        };
    }

    // Deletes the given profile from voltha KV
    rpc DeleteVoipUserProfile(common.Key) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/voip_user_profile/{key}/delete"
        };
    }

    // Disables the ONU, stops it from participating in the ranging process. different from DisableDevice
    rpc DisableOnuDevice (common.ID) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/disable_onu_device"
        };
    }

    // Enables the ONU at the PLOAM , enables the ONU to participate in the ranging process. different from EnableDevice
    rpc EnableOnuDevice (common.ID) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/enable_onu_device"
        };
    }

    
    // Disables the ONU at the PLOAM , different from DisableDevice. This would be used if the Device is not present in the VOLTHA
    rpc DisableOnuSerialNumber(device.OnuSerialNumberOnOLTPon) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/disable_onu_serial_number"
        };
    }

    // Disables the ONU at the PLOAM , different from EnableDevice. This would be used if the Device is not present in the VOLTHA
    rpc EnableOnuSerialNumber(device.OnuSerialNumberOnOLTPon) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/enable_onu_serial_number"
        };
    }

    // Update the Device configuration, for now only ip address updation is supported
    rpc UpdateDevice(device.UpdateDevice) returns(google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/update_device"
        };
    }

}

