syntax = "proto3";

// gRPC for our DBaaS central service
//
// notably uses gRPC-Gateway with OpenAPI
package tenant;

import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

option go_package = "pkg/service/tenant/;tenant";

service TenantService {
    rpc Registration (RegistrationReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs"
			body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "Registration"
        };
    }

    rpc SendVerificationEmail (SendVerificationEmailReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/verification-email"
			body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "Send Verification Email"
        };
    }

    rpc GetOrganization (google.protobuf.Empty) returns (Organization) {
        option (google.api.http) = {
            get: "/api/v1/orgs/me"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
               operation_id: "GetOrganization"
        };
    }

    rpc UpdateOrganization (UpdateOrgReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "UpdateOrganization"
        };
    }

    rpc UpdateOrgDefaultPayment (UpdateOrgDefaultPaymentReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/default-payment"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "UpdateOrgDefaultPayment"
        };
    }

    rpc ListUsers (ListUsersReq) returns (Users) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/users"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "ListUsers"
        };
    }

    rpc GetUserProfile (OrgIdReq) returns (UserProfile) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/users/me"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
               operation_id: "GetUserProfile"
        };
    }

    rpc UpdateUserProfile (UpdateUserProfileReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/users/me"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "UpdateUserProfile"
        };
    }

    rpc UpdateUser (UpdateUserReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            put: "/api/v1/orgs/{org_id}/users/{user_id}"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "UpdateUser"
        };
    }

    rpc DeleteUser (DeleteUserReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/users/{user_id}"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "DeleteUser"
        };
    }

    rpc CreateProject (CreateProjectReq) returns (ProjectId) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "CreateProject"
        };
    }

    rpc ListProjects (ListProjectsReq) returns (Projects) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "ListProjects"
        };
    }

    rpc UpdateProject (UpdateProjectReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            patch: "/api/v1/orgs/{org_id}/projects/{project_id}"
            body: "*"
        };
    }

    rpc ListProjectUsers (ListProjectUsersReq) returns (Users) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/users"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "ListProjectUsers"
        };
    }

    rpc InviteUser (InviteUserReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/users"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "InviteUser"
        };
    }

    rpc DeleteProjectUser (DeleteProjectUserReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            delete: "/api/v1/orgs/{org_id}/projects/{project_id}/users/{user_id}"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "DeleteProjectUser"
        };
    }

    rpc AcceptInvitation (AcceptInvitationReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/acception"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "AcceptInvitation"
        };
    }

    rpc CreateAuth0User (CreateAuth0UserReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/auth0-user"
            body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
            operation_id: "CreateAuth0User"
        };
    }

    rpc ListTenantAccessLogs (ListAccessLogReq) returns (ListAccessLogResp) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/access-logs"
        };
    }

    rpc GetProjectTrafficFilter (GetProjectTrafficFilterReq) returns (TrafficFilterResp) {
        option (google.api.http) = {
            get: "/api/v1/orgs/{org_id}/projects/{project_id}/traffic_filter"
        };
    }

    rpc UpdateProjectTrafficFilter (UpdateProjectTrafficFilterReq) returns (google.protobuf.Empty) {
        option (google.api.http) = {
            post: "/api/v1/orgs/{org_id}/projects/{project_id}/traffic_filter"
            body: "*"
        };
    }

    rpc GetClientIP (google.protobuf.Empty) returns (GetClientIPResp) {
        option (google.api.http) = {
            get: "/api/v1/my-ip"
        };
    }
}



message RegistrationReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["country", "first_name", "last_name", "email", "job", "company", "phone_number", "password", "accept_service", "recaptcha_response"]
        }
    };

    string country = 1;
    string first_name = 2;
    string last_name = 3;
    string email = 4;
    string job = 5;
    string company = 6;
    string phone_number = 7;
    string password = 8;
    bool accept_service = 9;
    string recaptcha_response = 10;
}

message SendVerificationEmailReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["email"]
        }
    };

    string email = 1;
}

message UpdateOrgReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "name", "timezone"]
        }
    };

    uint64 org_id = 1;
    string name = 2;
    int32 timezone = 3;
}

message UpdateOrgDefaultPaymentReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "default_source"]
        }
    };

    uint64 org_id = 1;
    string default_source = 2;
}

message User {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "email", "name", "status", "invite_time", "role"]
        }
    };

    uint64 id = 1;
    string email = 2;
    string name = 3;
    string status = 4;
    google.protobuf.Timestamp invite_time = 5;
    string role = 6;
}

message Users {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated User items = 2;
}

message ListUsersReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "page", "per_page", "email"]
        }
    };

    uint64 org_id = 1;
    uint32 page = 2;
    uint32 per_page = 3;
    string email = 4;
}

message ListProjectUsersReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "page", "per_page"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
    uint32 page = 3;
    uint32 per_page = 4;
}

message InviteUserReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "email", "role"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
    string email = 3;
    string role = 4;
}

message AcceptInvitationReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "email", "first_name", "last_name"]
        }
    };

    uint64 org_id = 1;
    string email = 2;
    string first_name = 3;
    string last_name = 4;
}

message CreateAuth0UserReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "token", "password"]
        }
    };

    uint64 org_id = 1;
    string token = 2;
    string password = 3;
}

message UserProfile {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "email", "first_name", "last_name", "role", "projects"]
        }
    };

    uint64 id = 1;
    string email = 2;
    string first_name = 3;
    string last_name = 4;
    string role = 5;
    repeated UserProject projects = 6;
}

message UpdateUserProfileReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "first_name", "last_name"]
        }
    };

    uint64 org_id = 1;
    string first_name = 2;
    string last_name = 3;
}

message DeleteUserReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "user_id"]
        }
    };

    uint64 org_id = 1;
    uint64 user_id = 2;
}

message DeleteProjectUserReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "user_id"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
    uint64 user_id = 3;
}

message AccessLog {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "happened_on", "user", "content"]
        }
    };

    uint64 id = 1;
    int64 happened_on = 2;
    string user = 3;
    string content = 4;
}

message ListAccessLogResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    uint32 total = 1;
    repeated AccessLog items = 2;
}

message ListAccessLogReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["page", "per_page", "user", "content", "start_time", "end_time", "org_id"]
        }
    };

    uint32 page = 1;
    uint32 per_page = 2;
    string user = 3;
    string content = 4;
    int64 start_time = 5;
    int64 end_time = 6;
    uint64 org_id = 7;
}

message GetProjectTrafficFilterReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
}

message GetClientIPResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["ip"]
        }
    };

    string ip = 1;
}

message TrafficFilter {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cidr", "description"]
        }
    };

    string cidr = 1;
    string description = 2;
}

message TrafficFilterList {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["cidrs"]
        }
    };

    repeated TrafficFilter cidrs = 1;
}

message UpdateTrafficFilterReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["traffic_filters", "cluster_id", "org_id", "project_id"]
        }
    };

    TrafficFilterList traffic_filters = 1;
    int64 cluster_id = 2;
	uint64 org_id = 3;
    uint64 project_id = 4;
}

message UpdateProjectTrafficFilterReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "traffic_filters"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
    TrafficFilterList traffic_filters = 3;
}

message OrgIdReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id"]
        }
    };

    uint64 org_id = 1;
}


message CreateProjectReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "name"]
        }
    };

    uint64 org_id = 1;
    string name = 2;
}

message ProjectId {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id"]
        }
    };

    uint64 id = 1;
}

message ListProjectsReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "page", "per_page"]
        }
    };

    uint64 org_id = 1;
    uint32 page = 2;
    uint32 per_page = 3;
}

message UpdateProjectReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "project_id", "name"]
        }
    };

    uint64 org_id = 1;
    uint64 project_id = 2;
    string name = 3;
}

message UpdateUserReq {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["org_id", "user_id", "role"]
        }
    };

    uint64 org_id = 1;
    uint64 user_id = 2;
    string role = 3;
}

message UserProject {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "name"]
        }
    };

    uint64 id = 1;
    string name = 2;
}

message Project {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "name", "active_clusters_count", "users_count"]
        }
    };

    uint64 id = 1;
    string name = 2;
    google.protobuf.Timestamp created_at = 3;
    uint32 active_clusters_count = 4;
    uint32 users_count = 5;
}

message Projects {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "items"]
        }
    };

    int32 total = 1;
    repeated Project items = 2;
}

message Organization {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["id", "name", "created_at", "email", "country", "timezone", "status", "plan", "total_credit", "remaining_credit", "active_clusters_count", "has_discount", "discount_description", "discount"]
        }
    };

    uint64 id = 1;
    string name = 2;
    google.protobuf.Timestamp created_at = 3;
    string email = 4;
    string country = 5;
    int32 timezone = 6;
    string status = 7;
    string plan = 8;
    int64 total_credit = 9;
    int64 remaining_credit = 10;
    uint32 active_clusters_count = 11;
    bool has_discount = 12;
    string discount_description = 13;
    double discount = 14;
}

message TrafficFilterResp {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["total", "traffic_filters"]
        }
    };

    int32 total = 1;
    TrafficFilterList traffic_filters = 2;
}