// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
// Modifications Copyright 2026 PingCAP, Inc.

//! Pure-Rust helpers for tests that need a legacy RocksDB-format SST fixture.

use std::{fs, path::Path};

use kvproto::import_sstpb::SstMeta;
use legacy_sst::{Options, Writer};
use uuid::Uuid;

pub fn calc_data_crc32(data: &[u8]) -> u32 {
    let mut digest = crc32fast::Hasher::new();
    digest.update(data);
    digest.finalize()
}

pub fn gen_sst_file<P: AsRef<Path>>(path: P, range: (u8, u8)) -> (SstMeta, Vec<u8>) {
    let mut writer = Writer::new(Options::default()).unwrap();
    for value in range.0..range.1 {
        writer.put(&keys::data_key(&[value]), &[value]).unwrap();
    }
    let output = writer.finish().unwrap();
    fs::write(path.as_ref(), &output.bytes).unwrap();
    read_sst_file(path, (&[range.0], &[range.1]))
}

pub fn gen_sst_file_with_kvs<P: AsRef<Path>>(
    path: P,
    kvs: &[(&[u8], &[u8])],
) -> (SstMeta, Vec<u8>) {
    let mut writer = Writer::new(Options::default()).unwrap();
    for (key, value) in kvs {
        writer.put(&keys::data_key(key), value).unwrap();
    }
    let output = writer.finish().unwrap();
    fs::write(path.as_ref(), &output.bytes).unwrap();

    let start_key = kvs.first().unwrap().0;
    let end_key = keys::next_key(kvs.last().unwrap().0);
    read_sst_file(path, (start_key, &end_key))
}

pub fn read_sst_file<P: AsRef<Path>>(path: P, range: (&[u8], &[u8])) -> (SstMeta, Vec<u8>) {
    let data = fs::read(path).unwrap();
    let mut meta = SstMeta::default();
    meta.set_uuid(Uuid::new_v4().as_bytes().to_vec());
    meta.mut_range().set_start(range.0.to_vec());
    meta.mut_range().set_end(range.1.to_vec());
    meta.set_crc32(calc_data_crc32(&data));
    meta.set_length(data.len() as u64);
    meta.set_cf_name("default".to_owned());
    (meta, data)
}
