syntax = "proto3";

package desam.client;

// 通用响应消息
message CommonResponse {
  bool success = 1;
  string message = 2;
  string error_code = 3;
}

// 作业状态枚举
enum JobStatus {
  UNKNOWN = 0;
  QUEUED = 1;          // 等待队列
  PREPARING = 2;       // 准备中
  RUNNING = 3;         // 执行中
  SUCCEEDED = 4;       // 成功
  FAILED = 5;          // 失败
  CANCELLED = 6;       // 已取消
  TIMEOUT = 7;         // 超时
  DATA_DEPENDENCY_ERROR = 8;  // 数据依赖异常
}

// 资源需求
message ResourceRequirement {
  int32 cpu_cores = 1;     // CPU核心数
  int64 memory_mb = 2;     // 内存(MB)
  int32 gpu_count = 3;     // GPU数量
  int64 disk_mb = 4;       // 磁盘空间(MB)
}

// 数据依赖
message DataDependency {
  string source_path = 1;   // 源路径
  string dest_path = 2;     // 目标路径
  bool is_input = 3;        // 是否为输入数据
}

// 作业信息
message Job {
  string job_id = 1;           // 作业ID
  string user_id = 2;          // 用户ID
  string name = 3;             // 作业名称
  string command = 4;          // 执行命令
  string working_dir = 5;      // 工作目录
  ResourceRequirement resources = 6;  // 资源需求
  repeated DataDependency dependencies = 7;  // 数据依赖
  map<string, string> metadata = 8;  // 元数据
  int64 submit_time = 9;       // 提交时间戳
  int64 start_time = 10;       // 开始时间戳
  int64 finish_time = 11;      // 完成时间戳
  JobStatus status = 12;       // 当前状态
  string error_message = 13;   // 错误信息
  string executor_id = 14;     // 分配的执行器ID
  // 新增字段
  map<string, string> env = 15;       // 环境变量
  int32 timeout = 16;                  // 超时时间(秒)
  int32 retries = 17;                  // 重试次数
  repeated string artifacts = 18;      // 数据依赖(逻辑文件名)
  map<string, string> labels = 19;     // 标签
  string description = 20;             // 描述
}

// 作业提交请求
message SubmitJobRequest {
  string api_key = 1;          // API密钥
  string user_id = 2;          // 用户ID
  string name = 3;             // 作业名称
  string command = 4;          // 执行命令
  string working_dir = 5;      // 工作目录
  ResourceRequirement resources = 6;  // 资源需求
  repeated DataDependency dependencies = 7;  // 数据依赖
  map<string, string> metadata = 8;  // 元数据
  // 新增字段
  map<string, string> env = 9;        // 环境变量
  int32 timeout = 10;                  // 超时时间(秒)
  int32 retries = 11;                  // 重试次数
  repeated string artifacts = 12;      // 数据依赖(逻辑文件名)
  map<string, string> labels = 13;     // 标签
  string description = 14;             // 描述
}

// 作业提交响应
message SubmitJobResponse {
  CommonResponse response = 1;  // 通用响应
  string job_id = 2;            // 分配的作业ID
  Job job = 3;                  // 作业信息
}

// 作业查询请求
message QueryJobRequest {
  string api_key = 1;          // API密钥
  string job_id = 2;           // 作业ID
}

// 作业查询响应
message QueryJobResponse {
  CommonResponse response = 1;  // 通用响应
  Job job = 2;                  // 作业信息
}

// 作业取消请求
message CancelJobRequest {
  string api_key = 1;          // API密钥
  string job_id = 2;           // 作业ID
}

// 作业取消响应
message CancelJobResponse {
  CommonResponse response = 1;  // 通用响应
  Job job = 2;                  // 更新后的作业信息
}

// 作业列表查询请求
message ListJobsRequest {
  string api_key = 1;          // API密钥
  string user_id = 2;          // 用户ID（可选，空则查询所有）
  JobStatus status = 3;        // 状态过滤（可选）
  int32 limit = 4;             // 限制数量（默认100）
  int32 offset = 5;            // 偏移量（分页）
}

// 作业列表查询响应
message ListJobsResponse {
  CommonResponse response = 1;  // 通用响应
  repeated Job jobs = 2;         // 作业列表
  int32 total = 3;              // 总数
}

// 作业日志请求
message GetJobLogsRequest {
  string api_key = 1;          // API密钥
  string job_id = 2;           // 作业ID
  int64 from_line = 3;         // 从第几行开始（默认0）
  int64 max_lines = 4;         // 最大行数（默认1000）
}

// 作业日志响应
message GetJobLogsResponse {
  CommonResponse response = 1;  // 通用响应
  string log_content = 2;       // 日志内容
  int64 total_lines = 3;        // 总行数
}

// 批量查询请求
message BatchQueryJobsRequest {
  string api_key = 1;          // API密钥
  repeated string job_ids = 2; // 作业ID列表
}

// 批量取消请求
message BatchCancelJobsRequest {
  string api_key = 1;          // API密钥
  repeated string job_ids = 2; // 作业ID列表
}

// 批量取消响应中的单个结果
message CancelResult {
  string job_id = 1;           // 作业ID
  bool success = 2;            // 是否成功
  string message = 3;          // 结果消息
}

// 批量取消响应
message BatchCancelJobsResponse {
  CommonResponse response = 1;      // 通用响应
  repeated CancelResult results = 2; // 各作业取消结果
}

// 文件信息
message FileInfo {
  string file_hash = 1;      // 文件哈希(SHA256)
  int64 file_size = 2;       // 文件大小(字节)
  string file_name = 3;      // 原始文件名
  string upload_time = 4;    // 上传时间(ISO8601格式)
}

// 文件树节点
message FileTreeNode {
  string path = 1;           // 文件路径
  string file_hash = 2;      // 文件哈希
  bool is_file = 3;          // 是否为文件(否则为目录)
  repeated FileTreeNode children = 4;  // 子节点
}

// 上传文件请求
message UploadFileRequest {
  string api_key = 1;        // API密钥
  string file_hash = 2;      // 文件哈希
  int64 file_size = 3;       // 文件大小
  string file_name = 4;      // 原始文件名
  bytes content = 5;         // 文件内容(流式上传时为分块)
  bool is_last_chunk = 6;    // 是否为最后一块
  string chunk_id = 7;       // 块ID(用于分块上传)
}

// 上传文件响应
message UploadFileResponse {
  CommonResponse response = 1;  // 通用响应
  string file_hash = 2;         // 文件哈希
  bool already_exists = 3;      // 文件是否已存在
}

// 查询缓存配额请求
message QueryCacheQuotaRequest {
  string api_key = 1;        // API密钥
}

// 查询缓存配额响应
message QueryCacheQuotaResponse {
  CommonResponse response = 1;  // 通用响应
  int64 total_quota = 2;        // 总配额(字节)
  int64 used_quota = 3;         // 已用配额(字节)
  int64 available_quota = 4;    // 可用配额(字节)
}

// 验证数据依赖请求
message VerifyDependenciesRequest {
  string api_key = 1;              // API密钥
  repeated string file_hashes = 2; // 文件哈希列表
  int64 total_size = 3;            // 总大小(字节)
}

// 验证数据依赖响应
message VerifyDependenciesResponse {
  CommonResponse response = 1;     // 通用响应
  repeated string missing_hashes = 2;  // 缺失的文件哈希
  repeated string existing_hashes = 3; // 已存在的文件哈希
  int64 missing_size = 4;              // 缺失文件总大小
  bool quota_sufficient = 5;           // 配额是否充足
}

// 提交作业时带数据依赖的请求
message SubmitJobWithArtifactsRequest {
  string api_key = 1;          // API密钥
  string user_id = 2;          // 用户ID
  string name = 3;             // 作业名称
  string command = 4;          // 执行命令
  string working_dir = 5;      // 工作目录
  ResourceRequirement resources = 6;  // 资源需求
  map<string, string> metadata = 7;  // 元数据
  map<string, string> env = 8;        // 环境变量
  int32 timeout = 9;                  // 超时时间(秒)
  int32 retries = 10;                 // 重试次数
  map<string, string> labels = 11;    // 标签
  string description = 12;            // 描述
  repeated string file_hashes = 13;   // 数据依赖文件哈希列表
  FileTreeNode file_tree = 14;        // 文件树结构
}

// 提交作业时带数据依赖的响应
message SubmitJobWithArtifactsResponse {
  CommonResponse response = 1;  // 通用响应
  string job_id = 2;            // 分配的作业ID
  Job job = 3;                  // 作业信息
  repeated string missing_hashes = 4;  // 缺失的文件哈希(需要先上传)
}

// Client服务定义
service ClientService {
  // 提交作业
  rpc SubmitJob(SubmitJobRequest) returns (SubmitJobResponse);

  // 查询作业状态
  rpc QueryJob(QueryJobRequest) returns (QueryJobResponse);

  // 取消作业
  rpc CancelJob(CancelJobRequest) returns (CancelJobResponse);

  // 列出作业
  rpc ListJobs(ListJobsRequest) returns (ListJobsResponse);

  // 获取作业日志
  rpc GetJobLogs(GetJobLogsRequest) returns (GetJobLogsResponse);

  // 批量查询作业
  rpc BatchQueryJobs(BatchQueryJobsRequest) returns (ListJobsResponse);

  // 批量取消作业
  rpc BatchCancelJobs(BatchCancelJobsRequest) returns (BatchCancelJobsResponse);

  // 查询缓存配额
  rpc QueryCacheQuota(QueryCacheQuotaRequest) returns (QueryCacheQuotaResponse);

  // 验证数据依赖
  rpc VerifyDependencies(VerifyDependenciesRequest) returns (VerifyDependenciesResponse);

  // 上传文件
  rpc UploadFile(stream UploadFileRequest) returns (UploadFileResponse);

  // 提交带数据依赖的作业
  rpc SubmitJobWithArtifacts(SubmitJobWithArtifactsRequest) returns (SubmitJobWithArtifactsResponse);
}
