/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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";

package skywalking.v3;

option java_multiple_files = true;
option java_package = "org.apache.skywalking.apm.network.ebpf.profiling.process.v3";
option go_package = "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/process/v3";

import "common/Common.proto";

// Define the detected processes and report them.
service EBPFProcessService {
    // Report discovered process in Rover
    rpc reportProcesses (EBPFProcessReportList) returns (EBPFReportProcessDownstream) {
    }

    // Keep the process alive in the backend.
    rpc keepAlive (EBPFProcessPingPkgList) returns (Commands) {
    }
}

message EBPFProcessReportList {
    repeated EBPFProcessProperties processes = 1;
    // An ID generated by eBPF agent, should be unique globally.
    string ebpfAgentID = 2;
}

message EBPFProcessProperties {
    // The Process metadata
    oneof metadata {
        EBPFHostProcessMetadata hostProcess = 1;
        EBPFKubernetesProcessMetadata k8sProcess = 2;
    }
}

message EBPFHostProcessMetadata {
    // [required] Entity metadata
    // Must ensure that entity information is unique at the time of reporting
    EBPFProcessEntityMetadata entity = 1;
    // [required] The Process id of the host
    int32 pid = 2;
    // [optional] properties of the process
    repeated KeyStringValuePair properties = 3;
}

// Process Entity metadata
message EBPFProcessEntityMetadata {
    // [required] Process belong layer name which define in the backend
    string layer = 1;
    // [required] Process belong service name
    string serviceName = 2;
    // [required] Process belong service instance name
    string instanceName = 3;
    // [required] Process name
    string processName = 4;
    // Process labels for aggregate from service
    repeated string labels = 5;
}

// Kubernetes process metadata
message EBPFKubernetesProcessMetadata {
    // [required] Entity metadata
    // Must ensure that entity information is unique at the time of reporting
    EBPFProcessEntityMetadata entity = 1;
    // [required] The Process id of the host
    int32 pid = 2;
    // [optional] properties of the process
    repeated KeyStringValuePair properties = 3;
}

message EBPFReportProcessDownstream {
    repeated EBPFProcessDownstream processes = 1;
}

message EBPFProcessDownstream {
    // Generated process id
    string processId = 1;
    // Locate the process by basic information
    oneof process {
        EBPFHostProcessDownstream hostProcess = 2;
        EBPFKubernetesProcessDownstream k8sProcess = 3;
    }
}

message EBPFHostProcessDownstream {
    int32 pid = 1;
}

// Kubernetes process downstream
message EBPFKubernetesProcessDownstream {
    int32 pid = 1;
}

message EBPFProcessPingPkgList {
    repeated EBPFProcessPingPkg processes = 1;
}

message EBPFProcessPingPkg {
    // Process entity
    EBPFProcessEntityMetadata entityMetadata = 1;
}