module os.neptune.kernel

use vm.io.io

use std.crypto.merkle

use vm.core.convert

// Transaction Kernel MAST tree layout (height 3, 8 leaves):
//   leaf 0: inputs          (Vec<RemovalRecord>)
//   leaf 1: outputs         (Vec<AdditionRecord>)
//   leaf 2: announcements   (Vec<Announcement>)
//   leaf 3: fee             (NativeCurrencyAmount)
//   leaf 4: coinbase        (Option<NativeCurrencyAmount>)
//   leaf 5: timestamp       (Timestamp)
//   leaf 6: mutator_set_hash (Digest)
//   leaf 7: merge_bit       (bool)
// Read the transaction kernel MAST hash from public input.
// Lock scripts call this (receives 5 field elements = 1 Digest).
pub fn read_lock_script_hash() -> Digest {
    io.read5()
}

// Read the three type-script public inputs:
//   1. kernel MAST hash
//   2. hash of salted input UTXOs
//   3. hash of salted output UTXOs
pub fn read_type_script_hashes() -> (Digest, Digest, Digest) {
    let kernel_hash: Digest = io.read5()
    let input_hash: Digest = io.read5()
    let output_hash: Digest = io.read5()
    (kernel_hash, input_hash, output_hash)
}

// Kernel field leaf indices (for use with merkle.step).
pub fn leaf_inputs() -> Field {
    0
}

pub fn leaf_outputs() -> Field {
    1
}

pub fn leaf_announcements() -> Field {
    2
}

pub fn leaf_fee() -> Field {
    3
}

pub fn leaf_coinbase() -> Field {
    4
}

pub fn leaf_timestamp() -> Field {
    5
}

pub fn leaf_mutator_set_hash() -> Field {
    6
}

pub fn leaf_merge_bit() -> Field {
    7
}

// Tree height of the kernel MAST tree.
pub fn tree_height() -> Field {
    3
}

// Authenticate a kernel field against the kernel MAST hash.
// Divines the leaf digest, verifies a depth-3 Merkle path,
// and returns the authenticated leaf digest.
pub fn authenticate_field(kernel_hash: Digest, leaf_idx: U32) -> Digest {
    merkle.authenticate_leaf3(kernel_hash, leaf_idx)
}

// Authenticate and extract the fee from the kernel.
// Returns the fee leaf digest (the fee value is encoded in the leaf).
pub fn authenticate_fee(kernel_hash: Digest) -> Digest {
    let idx: U32 = convert.as_u32(3)
    merkle.authenticate_leaf3(kernel_hash, idx)
}

// Authenticate and extract the timestamp from the kernel.
pub fn authenticate_timestamp(kernel_hash: Digest) -> Digest {
    let idx: U32 = convert.as_u32(5)
    merkle.authenticate_leaf3(kernel_hash, idx)
}

Local Graph