/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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";
option java_package = "org.onosproject.grpc.nb.net.host";

package nb.net.host;

import "net/HostProto.proto";
import "net/HostIdProto.proto";
import "net/ConnectPointProto.proto";

message getHostCountRequest {
}

message getHostCountReply {
    int32 host_count = 1;
}

message getHostsRequest {
}

message getHostsReply {
    repeated .net.HostProto host = 1;
}

message getHostRequest {
    .net.HostIdProto host_id = 1;
}

message getHostReply {
    .net.HostProto host = 1;
}

message getHostsByVlanRequest {
    string vlan_id = 1;
}

message getHostsByVlanReply {
    repeated .net.HostProto host = 1;
}

message getHostsByMacRequest {
    string mac = 1;
}

message getHostsByMacReply {
    repeated .net.HostProto host = 1;
}

message getHostsByIpRequest {
    string ip_address = 1;
}

message getHostsByIpReply {
    repeated .net.HostProto host = 1;
}

message getConnectedHostsRequest {
    oneof connected_host {
        .net.ConnectPointProto connect_point = 1;
        string deviceId = 2;
    }
}

message getConnectedHostsReply {
    repeated .net.HostProto host = 1;
}

message startMonitoringIpRequest {
    string ip_address = 1;
}

message startMonitoringIpReply {
}

message stopMonitoringIpRequest {
    string ip_address = 1;
}

message stopMonitoringIpReply {
}

message requestMacRequest {
    string ip_address = 1;
}

message requestMacReply {
}

// Host Interface exported by the server.
service HostService {
    // GRPC Obtains the host count.
    rpc getHostCount(getHostCountRequest) returns (getHostCountReply) {}

    // GRPC Obtains the hosts.
    rpc getHosts(getHostsRequest) returns (getHostsReply) {}

    // GRPC Obtains the host at a given HostId.
    rpc getHost(getHostRequest) returns (getHostReply) {}

    // GRPC Obtains the hosts at a given VlanId.
    rpc getHostsByVlan(getHostsByVlanRequest) returns (getHostsByVlanReply) {}

    // GRPC Obtains the hosts at a given MacAddress.
    rpc getHostsByMac(getHostsByMacRequest) returns (getHostsByMacReply) {}

    // GRPC Obtains the hosts at a given IpAddress.
    rpc getHostsByIp(getHostsByIpRequest) returns (getHostsByIpReply) {}

    // GRPC Obtains the hosts at a given connectPoint or DeviceId.
    rpc getConnectedHosts(getConnectedHostsRequest) returns (getConnectedHostsReply) {}

    // GRPC Requests the host service to monitor hosts with the given IP address.
    rpc startMonitoringIp(startMonitoringIpRequest) returns (startMonitoringIpReply) {}

    // GRPC Stops the host service from monitoring an IP address.
    rpc stopMonitoringIp(stopMonitoringIpRequest) returns (stopMonitoringIpReply) {}

    // GRPC Requests the host service to resolve the MAC address for the given IP address.
    rpc requestMac(requestMacRequest) returns (requestMacReply) {}
}