//! Raft command types for log entries.

/// Command opcode for KV operations.
pub const CMD_KV: u8 = 0;

/// Command opcode for region split.
pub const CMD_SPLIT: u8 = 1;

/// Encode a Split command payload.
#[allow(dead_code)]
pub fn encode_split_command(region_id: u64, split_key: &[u8], new_region_id: u64) -> Vec<u8> {
    let mut buf = Vec::with_capacity(1 + 8 + 4 + split_key.len() + 8);
    buf.push(CMD_SPLIT);
    buf.extend_from_slice(&region_id.to_be_bytes());
    buf.extend_from_slice(&(split_key.len() as u32).to_be_bytes());
    buf.extend_from_slice(split_key);
    buf.extend_from_slice(&new_region_id.to_be_bytes());
    buf
}

/// Decode a Split command payload.
/// Returns (region_id, split_key, new_region_id).
pub fn decode_split_command(data: &[u8]) -> Option<(u64, Vec<u8>, u64)> {
    if data.len() < 1 + 8 + 4 + 8 {
        return None;
    }
    let region_id = u64::from_be_bytes(data[1..9].try_into().ok()?);
    let klen = u32::from_be_bytes(data[9..13].try_into().ok()?) as usize;
    if data.len() < 13 + klen + 8 {
        return None;
    }
    let split_key = data[13..13 + klen].to_vec();
    let new_region_id = u64::from_be_bytes(data[13 + klen..13 + klen + 8].try_into().ok()?);
    Some((region_id, split_key, new_region_id))
}
