// (c) 2025 ANSYS, Inc. Unauthorized use, distribution, or duplication is prohibited. ANSYS Confidential Information
syntax = "proto3";

import "ansys/api/speos/file/v1/file_transfer.proto";
import "ansys/api/speos/results/v1/ray_path.proto";
import "google/protobuf/duration.proto";

package ansys.api.speos.job.v2;

service JobsManager {
	// Create a Job
	rpc Create(Create_Request) returns (Create_Response) {}
	// Read a Job
	rpc Read(Read_Request) returns (Read_Response) {}
	// Update a Job
	rpc Update(Update_Request) returns (Update_Response) {}
	// Delete a Job
	rpc Delete(Delete_Request) returns (Delete_Response) {}
	// List all Jobs in manager
	rpc List(List_Request) returns (List_Response) {}
}

message Job {
	string name = 7; // Job name
	string description = 8; // Job descrition
	map<string, string> metadata = 9; // User defined metadatas

	string scene_guid = 1; // Guid of the Scene in ScenesManager
	string simulation_path = 2; // Simulation path in the scene that will be used by the job
	Type job_type = 3; // Type of the job : CPU, GPU
	oneof simu_properties {
		DirectMCSimulationProperties direct_mc_simulation_properties = 4; // Properties to be filled for simulation based on DirectMCSimulationTemplate
		InverseMCSimulationProperties inverse_mc_simulation_properties = 5; // Properties to be filled for simulation based on InverseMCSimulationTemplate 
		InteractiveSimulationProperties interactive_simulation_properties = 6; // Properties to be filled for simulation based on Interactive 
	}

	enum Type {
		CPU = 0;
		GPU = 1;
	}
	enum State {
		QUEUED = 0;
		RUNNING = 1;
		PAUSED = 2;
		STOPPED = 3;
		FINISHED = 4;
		IN_ERROR = 5;
	}

	// If several stop conditions are set, the first condition reached ends the simulation.
	// If no stop condition is set, the simulation ends when you stop the process.
	message DirectMCSimulationProperties {
		optional int64 stop_condition_rays_number = 1; // To stop the simulation after a certain number of rays were sent
		optional int64 stop_condition_duration = 2; // To stop the simulation after a certain duration
		int32 automatic_save_frequency = 3; // Define a backup interval (s). This option is useful when computing long simulations. But a reduced number of save operations naturally increases the simulation performance
	}

	// If several stop conditions are set, the first condition reached ends the simulation.
	// If no stop condition is set, the simulation ends when you stop the process.
	message InverseMCSimulationProperties {
		oneof optimized_propagation {
			OptimizedPropagationNone optimized_propagation_none = 1; // No optimization. Do not forget to fill stop conditions if needed.
			OptimizedPropagationRelative optimized_propagation_relative = 2;
			OptimizedPropagationAbsolute optimized_propagation_absolute = 3;
		}
		optional int64 stop_condition_duration = 5; // To stop the simulation after a certain duration
		int32 automatic_save_frequency = 4; // Define a backup interval (s). This option is useful when computing long simulations. But a reduced number of save operations naturally increases the simulation performance

		// No optimization : the same number of passes is used for each pixel of the image
		message OptimizedPropagationNone {
			optional uint32 stop_condition_passes_number = 1; // To stop the simulation after a certain number of passes
		}
		// The algorithm adapts the number of passes per pixel to send the optimal number of rays according to the signal each pixel needs.
		// As a result, the SNR is adequate in areas where pixels need more rays, thus giving a balanced image.
		// The Optimized propagation algorithm is only compatible with the Radiance sensors.
		message OptimizedPropagationRelative {
			uint32 min_pass_number = 1; // Minimum number of passes without pass optimization.
			uint32 stop_condition_relative_value = 2; // Relative pixel standard deviation threshold, in percent. Value expected from 0 to 100.
		}
		// The algorithm adapts the number of passes per pixel to send the optimal number of rays according to the signal each pixel needs.
		// As a result, the SNR is adequate in areas where pixels need more rays, thus giving a balanced image.
		// The Optimized propagation algorithm is only compatible with the Radiance sensors.
		message OptimizedPropagationAbsolute {
			uint32 min_pass_number = 1; // Minimum number of passes without pass optimization.
			uint32 stop_condition_absolute_value = 2; // Absolute photometric value of pixel standard deviation threshold
		}
	}

	message InteractiveSimulationProperties {
		repeated RaysNumberPerSource rays_number_per_sources = 1; // If a source present in Scene::SimulationInstance is not mentioned here, its rays_nb is defaulted to 100.
		bool light_expert = 2; // To generate a light expert file.
		bool impact_report = 3; // To integrate details like number of impacts, position and surface state to the HTML simulation report.
		
		message RaysNumberPerSource {
			string source_path = 1; // Path to the source. Hint: same path that was given in Scene::SimulationInstance
			optional uint32 rays_nb = 3; // Number of rays sent by the source referenced via its source_path. Default 100
		}
	}
}

// Request to create a Job in JobsManager
message Create_Request {
	Job job = 3; // Job characteristics
}
message Create_Response {
	string guid = 1; // Guid of the Job created in JobsManager
}

// Request to read a Job in JobsManager
message Read_Request {
	string guid = 1; // Guid of the Job to be read
}
message Read_Response {
	Job job = 1; // Job corresponding to the guid given in Read_Request
}

// Request to update a Job in JobsManager
message Update_Request {
	string guid = 1; // Guid of the Job to be updated
	Job job = 2; // Job that will be used for the update
}
message Update_Response {}

// Request to delete a Job in JobsManager
message Delete_Request {
	string guid = 1; // Guid of the Job to be deleted
}
message Delete_Response {}

message List_Request {}
message List_Response {
	repeated string guids = 1; // Guids of the Jobs in JobsManager
}


// Service to handle a job
service JobActions {
	// Get the state of a Job
	rpc GetState(GetState_Request) returns (GetState_Response) {}
	// Start a Job
	rpc Start(Start_Request) returns (Start_Response) {}
	// Stop a Job
	rpc Stop(Stop_Request) returns (Stop_Response) {}
	// Get error of a Job
	rpc GetError(GetError_Request) returns (GetError_Response) {}
	// Get the results of a Job
	rpc GetResults(GetResults_Request) returns (GetResults_Response) {}
	// Get Information about a Job
	rpc GetInformation(GetInformation_Request) returns (GetInformation_Response) {  option deprecated = true; }
	// Get RayPaths generated by a Job based on an interactive simulation
	rpc GetRayPaths(GetRayPaths_Request) returns (stream ansys.api.speos.results.v1.RayPath) {}
	// Get progress status about a Job
	rpc GetProgressStatus(GetProgressStatus_Request) returns (GetProgressStatus_Response) {}
}

message GetState_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message GetState_Response {
	Job.State state = 1;
}

message Start_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message Start_Response {}

message Stop_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message Stop_Response {}

message GetError_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message GetError_Response {
	string name = 1;
	string category = 2;
	int32 severity = 3;
	string request = 4;
	string diagnostic = 5;
	string advice = 6;
	string error_file = 7;
	int32 error_line = 8;
}

message Result {
	oneof result {
		string path = 1; // Result path on the server
		ansys.api.speos.file.v1.Upload_Response upload_response = 2; // Result uploaded to server's file system (via FileTransferService) -> returns Upload_Response
	}
}
message GetResults_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message GetResults_Response {
	repeated Result results = 1; // List of the Job results
}

message GetInformation_Request {
	option deprecated = true; // Use GetProgressStatus instead
	string guid = 1; // Guid of the Job in JobsManager.
}
message GetInformation_Response {
	option deprecated = true; // Use GetProgressStatus instead
	string title = 1;
	string name = 2;
	string infos = 3;
	double progress = 4; // value between 0.0 and 1.0
	google.protobuf.Duration elapsed_time = 5;
	google.protobuf.Duration remaining_time = 6;
	repeated string process_unit_models = 7; // Depending on the Job::Type, list of the CPU or GPU models
	uint64 rays_number = 8; // Number of rays emitted since the (re)start of the simulation
	uint64 rays_number_per_second = 9; // Number of rays emitted in the last second
}

message GetRayPaths_Request {
	string guid = 1; // Guid of the Job in JobsManager.
	optional bool raw_data = 4; // Boolean to get the wavelengths in response stream
	optional bool display_data = 5; // Boolean to get the colors (RGB24 format) in response stream
}

message GetProgressStatus_Request {
	string guid = 1; // Guid of the Job in JobsManager.
}
message GetProgressStatus_Response {
	string title = 1;
	string name = 2;
	string infos = 3;
	double progress = 4; // value between 0.0 and 1.0
	google.protobuf.Duration elapsed_time = 5;
	google.protobuf.Duration remaining_time = 6;
	repeated string process_unit_models = 7; // Depending on the Job::Type, list of the CPU or GPU models
	uint64 rays_number = 8; // Number of rays emitted since the (re)start of the simulation
	uint64 rays_number_per_second = 9; // Number of rays emitted in the last second
}