syntax = "proto3";
package ezshare;

import "google/protobuf/timestamp.proto";

option go_package = "gitea.benny.dog/torjus/ezshare/pb";

/////////////////////
// Common messages //
/////////////////////
message Empty {}

////////////////////////
// FILE RELATED STUFF //
////////////////////////
message File {
    string file_id = 1;
    bytes data = 2;

    message Metadata {
        google.protobuf.Timestamp uploaded_on = 1;
        google.protobuf.Timestamp expires_on = 2;
        string original_filename = 3;
        string passcode = 4;
        int64 current_views = 5;
        int64 max_views = 6;
        string owner = 7;
    };

    Metadata metadata = 3;
};


// Service messages
// Upload
message UploadFileRequest {
    bytes data = 1;
    string original_filename = 2;
    google.protobuf.Timestamp expires_on = 3;
    int64 max_views = 4;
    bool with_passcode = 5;
}
message UploadFileResponse {
    string id = 1;
    string file_url = 2;
}

// Get
message GetFileRequest {
    string id = 1;
    string passcode = 2;
}
message GetFileResponse {
    File file = 1;
}

// Delete
message DeleteFileRequest {
    string id = 1;
}
message DeleteFileResponse {
}

// List
message ListFilesRequest {}
message ListFilesResponse {
    message ListFileInfo {
        string file_id = 1;
        File.Metadata metadata = 2;
    }
    repeated ListFileInfo files = 1;
}

service FileService {
    rpc UploadFile(UploadFileRequest) returns (UploadFileResponse) {}
    rpc GetFile(GetFileRequest) returns (GetFileResponse) {}
    rpc DeleteFile(DeleteFileRequest) returns (DeleteFileResponse) {}
    rpc ListFiles(ListFilesRequest) returns (ListFilesResponse) {}
}

////////////////////////
// USER RELATED STUFF //
////////////////////////
message User {
    string id = 1;
    string username = 2;
    bytes hashed_password = 3;
    enum Role {
        UNKNOWN = 0;
        UNAPPROVED = 1;
        VIEWONLY = 4;
        USER = 7;
        ADMIN = 10;
    }
    Role user_role = 4;
    bool active = 5;
}

// Register
message RegisterUserRequest {
    string username = 1;
    string password = 2;
}
message RegisterUserResponse {
    string id = 1;
    string token = 2;
}

// Login
message LoginUserRequest {
    string username = 1;
    string password = 2;
}
message LoginUserResponse {
    bytes client_cert = 1;
    bytes client_key = 2;
}

// List
message ListUsersRequest {
}
message ListUsersResponse {
    repeated User users = 1;
}

// Approve
message ApproveUserRequest {
    string user_id = 1;
}


// Change password
message ChangePasswordRequest {
    string old_password = 1;
    string new_password = 2;
}

service UserService {
    rpc Register(RegisterUserRequest) returns (RegisterUserResponse) {}
    rpc Login(LoginUserRequest) returns (LoginUserResponse) {}
    rpc List(ListUsersRequest) returns (ListUsersResponse) {}
    rpc Approve(ApproveUserRequest) returns (Empty) {}
    rpc ChangePassword(ChangePasswordRequest) returns (Empty) {}
}

///////////////////////////////
// Certificate related stuff //
///////////////////////////////

// List
message ListCertificatesResponse {
    message CertificateInfo {
        string serial = 1;
        string owner_id = 2;
        string owner_username = 3;
    }
    repeated CertificateInfo certificates = 1;
}

// Revoke
message RevokeCertificateRequest {
    string serial = 1;
}

service CertificateService {
    rpc ListCertificates(Empty) returns (ListCertificatesResponse) {}
    rpc RevokeCertificate(RevokeCertificateRequest) returns (Empty) {}
}

//////////////////////////
// Binary related stuff //
//////////////////////////

message Binary {
    string version = 1;
    string arch = 2;
    string os = 3;
    bytes data = 4;
}

message UploadBinariesRequest {
    repeated Binary binaries = 2;
}

message GetBinaryRequest {
    string version = 1;
    string arch = 2;
    string os = 3;
}

message LatestVersionResponse {
    string version = 1;
}

service BinaryService {
    rpc UploadBinaries(UploadBinariesRequest) returns (Empty) {}
    rpc GetBinary(GetBinaryRequest) returns (Binary) {}
    rpc GetLatestVersion(Empty) returns (LatestVersionResponse) {}
}