/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

syntax = "proto3";

import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

option go_package = "github.com/featureform/metadata/proto";

package featureform.serving.metadata.proto;

service Metadata {
    rpc ListFeatures(Empty) returns (stream Feature);
    rpc CreateFeatureVariant(FeatureVariant) returns (Empty);
    rpc GetFeatures(stream Name) returns (stream Feature);
    rpc GetFeatureVariants(stream NameVariant) returns (stream FeatureVariant);
    rpc ListLabels(Empty) returns (stream Label);
    rpc CreateLabelVariant(LabelVariant) returns (Empty);
    rpc GetLabels(stream Name) returns (stream Label);
    rpc GetLabelVariants(stream NameVariant) returns (stream LabelVariant);
    rpc ListTrainingSets(Empty) returns (stream TrainingSet);
    rpc CreateTrainingSetVariant(TrainingSetVariant) returns (Empty);
    rpc GetTrainingSets(stream Name) returns (stream TrainingSet);
    rpc GetTrainingSetVariants(stream NameVariant) returns (stream TrainingSetVariant);
    rpc ListSources(Empty) returns (stream Source);
    rpc CreateSourceVariant(SourceVariant) returns (Empty);
    rpc GetSources(stream Name) returns (stream Source);
    rpc GetSourceVariants(stream NameVariant) returns (stream SourceVariant);
    rpc ListUsers(Empty) returns (stream User);
    rpc CreateUser(User) returns (Empty);
    rpc GetUsers(stream Name) returns (stream User);
    rpc ListProviders(Empty) returns (stream Provider);
    rpc CreateProvider(Provider) returns (Empty);
    rpc GetProviders(stream Name) returns (stream Provider);
    rpc ListEntities(Empty) returns (stream Entity);
    rpc CreateEntity(Entity) returns (Empty);
    rpc GetEntities(stream Name) returns (stream Entity);
    rpc ListModels(Empty) returns (stream Model);
    rpc CreateModel(Model) returns (Empty);
    rpc GetModels(stream Name) returns (stream Model);
    rpc SetResourceStatus(SetStatusRequest) returns (Empty);
    rpc RequestScheduleChange(ScheduleChangeRequest) returns (Empty);
}

service Api {
    rpc CreateUser(User) returns (Empty);
    rpc CreateProvider(Provider) returns (Empty);
    rpc CreateSourceVariant(SourceVariant) returns (Empty);
    rpc CreateEntity(Entity) returns (Empty);
    rpc CreateFeatureVariant(FeatureVariant) returns (Empty);
    rpc CreateLabelVariant(LabelVariant) returns (Empty);
    rpc CreateTrainingSetVariant(TrainingSetVariant) returns (Empty);
    rpc CreateModel(Model) returns (Empty);
    rpc RequestScheduleChange(ScheduleChangeRequest) returns (Empty);
    rpc GetUsers(stream Name) returns (stream User);
    rpc GetFeatures(stream Name) returns (stream Feature);
    rpc GetFeatureVariants(stream NameVariant) returns (stream FeatureVariant);
    rpc GetLabels(stream Name) returns (stream Label);
    rpc GetLabelVariants(stream NameVariant) returns (stream LabelVariant);
    rpc GetTrainingSets(stream Name) returns (stream TrainingSet);
    rpc GetTrainingSetVariants(stream NameVariant) returns (stream TrainingSetVariant);
    rpc GetSources(stream Name) returns (stream Source);
    rpc GetSourceVariants(stream NameVariant) returns (stream SourceVariant);
    rpc GetProviders(stream Name) returns (stream Provider);
    rpc GetEntities(stream Name) returns (stream Entity);
    rpc GetModels(stream Name) returns (stream Model);
    rpc ListFeatures(Empty) returns (stream Feature);
    rpc ListLabels(Empty) returns (stream Label);
    rpc ListTrainingSets(Empty) returns (stream TrainingSet);
    rpc ListSources(Empty) returns (stream Source);
    rpc ListUsers(Empty) returns (stream User);
    rpc ListProviders(Empty) returns (stream Provider);
    rpc ListEntities(Empty) returns (stream Entity);
    rpc ListModels(Empty) returns (stream Model);
    rpc WriteFeatures(stream StreamingFeatureVariant) returns (Empty);
    rpc WriteLabels(stream StreamingLabelVariant) returns (Empty);
}

message Name {
    string name = 1;
}


message ResourceStatus {
    enum Status {
        NO_STATUS = 0;
        CREATED = 1;
        PENDING = 2;
        READY = 3;
        FAILED = 4;
      }
    Status status = 1;
    string error_message = 2;
}

enum ResourceType {
    FEATURE = 0;
    LABEL = 1;
    TRAINING_SET = 2;
    SOURCE = 3;
    FEATURE_VARIANT = 4;
    LABEL_VARIANT = 5;
    TRAINING_SET_VARIANT = 6;
    SOURCE_VARIANT = 7;
    PROVIDER = 8;
    ENTITY = 9;
    MODEL = 10;
    USER = 11;
}

message ResourceID {
    NameVariant resource = 1;
    ResourceType resource_type = 2;
}

message SetStatusRequest {
    ResourceID resource_id = 1;
    ResourceStatus status = 2;
}

message ScheduleChangeRequest {
    ResourceID resource_id = 1;
    string schedule = 2;
}

message NameVariant {
    string name = 1;
    string variant = 2;
}

message Empty {}

message Feature {
    string name = 1;
    ResourceStatus status = 2;
    string default_variant = 3;
    repeated string variants = 4;
}

message Columns {
    string entity = 1;
    string value = 2;
    string ts = 3;
}

message PythonFunction {
    bytes query = 1;
}

message Stream {
    string offline_provider = 1;
}

enum ComputationMode {
    PRECOMPUTED = 0;
    CLIENT_COMPUTED = 1;
    STREAMING = 2;
}

message FeatureVariant {
    string name = 1;
    string variant = 2;
    NameVariant source = 3;
    string type = 4;
    string entity = 5;
    google.protobuf.Timestamp created = 6;
    string owner = 7;
    string description = 8;
    string provider = 9;
    ResourceStatus status = 10;
    repeated NameVariant trainingsets = 11;
    oneof location {
        Columns columns = 12;
        PythonFunction function = 17;
        Stream stream = 21;
    }
    google.protobuf.Timestamp last_updated = 13;
    string schedule = 14;
    Tags tags = 15;
    Properties properties = 16;
    ComputationMode mode = 18;
    bool is_embedding = 19;
    int32 dimension = 20;
}

message FeatureLag {
    string feature = 1;
    string variant = 2;
    string name = 3;
    google.protobuf.Duration lag = 4;
}

message Label {
    string name = 1;
    ResourceStatus status = 2;
    string default_variant = 3;
    repeated string variants = 4;
}

message LabelVariant {
    string name = 1;
    string variant = 2;
    string description = 3;
    string type = 4;
    NameVariant source = 5;
    string entity = 6;
    google.protobuf.Timestamp created = 7;
    string owner = 8;
    string provider = 9;
    ResourceStatus status = 10;
    repeated NameVariant trainingsets = 11;
    oneof location {
        Columns columns = 12;
        Stream stream = 16;
    }
    Tags tags = 13;
    Properties properties = 14;
}

message Provider {
    string name = 1;
    string description = 2;
    string type = 3;
    string software = 4;
    string team = 5;
    bytes serialized_config = 6;
    ResourceStatus status = 7;
    repeated NameVariant sources = 8;
    repeated NameVariant features = 9;
    repeated NameVariant trainingsets = 10;
    repeated NameVariant labels = 11;
    Tags tags = 12;
    Properties properties = 13;
}

message TrainingSet {
    string name = 1;
    ResourceStatus status = 2;
    string default_variant = 3;
    repeated string variants = 4;
}

message TrainingSetVariant {
    string name = 1;
    string variant = 2;
    string description = 3;
    string owner = 4;
    google.protobuf.Timestamp created = 5;
    string provider = 6;
    ResourceStatus status = 7;
    repeated NameVariant features = 8;
    NameVariant label = 9;
    google.protobuf.Timestamp last_updated = 13;
    string schedule = 14;
    repeated FeatureLag feature_lags = 15;
    Tags tags = 16;
    Properties properties = 17;
}

message Entity {
    string name = 1;
    string description = 2;
    ResourceStatus status = 3;
    repeated NameVariant features = 4;
    repeated NameVariant labels = 5;
    repeated NameVariant trainingsets = 6;
    Tags tags = 7;
    Properties properties = 8;
}

message Model {
    string name = 1;
    string description = 2;
    repeated NameVariant features = 3;
    repeated NameVariant labels = 4;
    repeated NameVariant trainingsets = 5;
    Tags tags = 6;
    Properties properties = 7;
}

message User {
    string name = 1;
    ResourceStatus status = 2;
    repeated NameVariant features = 3;
    repeated NameVariant labels = 4;
    repeated NameVariant trainingsets = 5;
    repeated NameVariant sources = 6;
    Tags tags = 8;
    Properties properties = 9;
}

message Source {
    string name = 1;
    ResourceStatus status = 2;
    string default_variant = 3;
    repeated string variants = 4;
}

message SourceVariant {
    string name = 1;
    string variant = 2;
    oneof definition {
        Transformation transformation = 14;
        PrimaryData primaryData = 15;
    }
    string owner = 4;
    string description = 5;
    string provider = 6;
    google.protobuf.Timestamp created = 7;
    ResourceStatus status = 8;
    string table = 9;
    repeated NameVariant trainingsets = 10;
    repeated NameVariant features = 11;
    repeated NameVariant labels = 12;
    google.protobuf.Timestamp last_updated = 13;
    string schedule = 16;
    Tags tags = 17;
    Properties properties = 18;
}

message Transformation {
    oneof type {
        SQLTransformation SQLTransformation= 1;
        DFTransformation DFTransformation= 2;
    }
    oneof args {
        KubernetesArgs kubernetes_args = 3;
    }
}

message KubernetesResourceSpecs {
    string cpu_request = 1;
    string cpu_limit = 2;
    string memory_request = 3;
    string memory_limit = 4;
}

message KubernetesArgs {
    string docker_image= 1;
    KubernetesResourceSpecs specs = 2;
}

message SQLTransformation {
    string query = 1;
    repeated NameVariant source = 2;
}

message DFTransformation {
    bytes query = 1;
    repeated NameVariant inputs = 2; 
    string source_text = 3;
}

message PrimaryData {
    oneof location {
        PrimarySQLTable table = 1;
    }
}

message PrimarySQLTable {
    string name = 1;
}

message Tags {
    repeated string tag = 1;
}

message Property {
    oneof value {
        string string_value = 1;
    }
}

message Properties {
    map<string, Property> property = 1;
}

message StreamingFeatureVariant {
    string name = 1;
    string variant = 2;
    string entity = 3;
    string value = 4;
    google.protobuf.Timestamp ts = 5;
}

message StreamingLabelVariant {
    string name = 1;
    string variant = 2;
    string value = 3;
    string entity = 4;
    google.protobuf.Timestamp ts = 5;
}