use std::fs;
use std::path::Path;
use std::process::Command;
use sha2::{Sha256, Digest};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct OracleExecutionReceipt {
pub execution_hash: String,
pub solver_urn: String,
pub tokens_burned: i64,
}
pub fn execute_pvv_pipeline(
payload: &str,
solver_urn: &str,
tokens_burned: i64,
) -> Result<OracleExecutionReceipt, String> {
let mut clean_lines = Vec::new();
for line in payload.lines() {
if line.trim().starts_with("# CORESIG:") {
continue;
}
clean_lines.push(line);
}
let clean_payload = clean_lines.join("\n");
let is_python = clean_payload.contains("import ") || clean_payload.contains("def ") || clean_payload.contains("class ");
if is_python {
let temp_name = format!("pvv_syntax_check_{}.py", rand::random::<u64>());
let temp_path = std::env::temp_dir().join(temp_name);
fs::write(&temp_path, &clean_payload)
.map_err(|e| format!("Failed to write temporary file for validation: {}", e))?;
let python_exe = std::env::var("PYTHON").unwrap_or_else(|_| "python".to_string());
let output = Command::new(python_exe)
.arg("-m")
.arg("py_compile")
.arg(&temp_path)
.output();
let _ = fs::remove_file(&temp_path);
match output {
Ok(out) if out.status.success() => {
log::info!("Python syntax check passed.");
}
Ok(out) => {
let err_msg = String::from_utf8_lossy(&out.stderr).trim().to_string();
return Err(format!("Python SyntaxError: {}", err_msg));
}
Err(e) => {
log::warn!("Failed to invoke python interpreter for syntax check: {}", e);
}
}
} else {
if let Err(e) = syn::parse_str::<syn::File>(&clean_payload) {
return Err(format!("Rust SyntaxError: Failed to parse AST: {}", e));
}
log::info!("Rust AST parsed successfully.");
}
let mut hasher = Sha256::new();
hasher.update(clean_payload.as_bytes());
let execution_hash = hex::encode(hasher.finalize());
Ok(OracleExecutionReceipt {
execution_hash,
solver_urn: solver_urn.to_string(),
tokens_burned,
})
}