#!/bin/bash
# PARAM 1: PATH

SHITFILE="$(mktemp)"
HIVEPATH="$1";

# chararr length, format, args...
function chararr() {
	printf "$2" "${@:3}" > "$SHITFILE";
	truncate "$SHITFILE" -s "$1";
	cat "$SHITFILE" >> "$HIVEPATH";
}

# wchararrle length, format, args
function wchararrle() {
	printf "$2" "${@:3}" | iconv -t utf-16le > "$SHITFILE";
	truncate "$SHITFILE" -s "$1";
	cat "$SHITFILE" >> "$HIVEPATH";
}

# i1le value
function i1le() {
	printf "\\$(printf "%o" $(( $1 & 255 )))" >> "$HIVEPATH";
}

# i2le value
function i2le() {
	I1=$(printf "%o" $((($1 >> 8) & 255 )));
	I0=$(printf "%o" $((($1     ) & 255 )));

	printf "\\$I0\\$I1" >> "$HIVEPATH";
}

# i4le value
function i4le() {
	I3=$(printf "%o" $((($1 >> 24 ) & 255 )) );
	I2=$(printf "%o" $((($1 >> 16 ) & 255 )) );
	I1=$(printf "%o" $((($1 >>  8 ) & 255 )) );
	I0=$(printf "%o" $((($1       ) & 255 )) );

	printf "\\$I0\\$I1\\$I2\\$I3" >> "$HIVEPATH";
}

# i8le value
function i8le() {
	C1=$(( $1 >> 32 ));
	C0=$(( $1 & 4294967295 ));

	i4le $C0;
	i4le $C1;
}

# i1lea values...
function i1lea() {
	while [ -v 1 ]; do
		i1le $1;
		shift;
	done;
}

# i2lea values...
function i2lea() {
	while [ -v 1 ]; do
		i2le $1;
		shift;
	done;
}

# i4lea values...
function i4lea() {
	while [ -v 1 ]; do
		i4le $1;
		shift;
	done
}

# i8lea values...
function i8lea() {
	while [ -v 1 ]; do
		i8le $1;
		shift;
	done
}

# pad count
function pad() {
	>"$SHITFILE";
	truncate -s "$1" "$SHITFILE";
	cat "$SHITFILE" >> "$HIVEPATH";
}

if [ -n "$HIVEPATH" ]; then
	echo "MAKE HIVE AT $1";
	
	# clear file
	>test.dat

	# base block
	chararr    4 "regf"
	i4lea      0 0
	i8le       0
	i4lea      1 6 0 1 352 4096 0
	wchararrle 64 "%s" "$(basename "$HIVEPATH")"
	pad        396

	for w in $(hexdump "$HIVEPATH" -v -e '"%i\n"'); do
		if [ ! -v CHKSUM ]; then
			CHKSUM=$w;
		else
			CHKSUM=$(( $CHKSUM ^ $w ));
		fi
	done
	i4le       $CHKSUM # checksum but fuck you we dont check the sum
	
	pad        3576
	i4lea      0 0

	# hive bin
	chararr 4 "hbin"
	i4lea   0 4096
	i8lea   0 0
	i4le    0

	# LRSS hive bin data block 
	i4le    -16
	chararr 2 "Ld" # (!) non standard 
	i1le    1  # The tree alloc list be invalid
	i1le    0  # reserved
	i4le    1  # number of 4096 byte chunks (alloc list byte length is this * 128 + 24)
	i4le    48 # offset from bin start to alloc list

	# LRSS hive bin alloc list
	i4le    -152
	chararr 2 "La" # (!) non standard
	pad     2
	i2lea   70 71 73 77 85 101 133 # alloc list offsets
	pad     130

	for (( i=0; i < 19 ; i++ )); do
		i8le 4294967288;
	done

	# root key
	i4le    -80
	chararr 2 "nk"
	i2le    0
	i8le    0
	i4le    0
	i4le    0
	i4le    0
	i4le    0
	i4le    432
	i4le    0
	i4le    0
	i4le    0
	i4le    440
	i4le    0
	i4le    0
	i4le    0
	i4le    0
	i4le    0
	i4le    0
	i2le    0
	i2le    0

	# root key subkeys
	i4le    -8
	chararr 2 "li"
	i2le    0

	# root key security info B)
	i4le    -24
	chararr 2 "sk"
	i2le    0
	i4le    440 # fuck the header just link to ourself, this will surely have no consequences in the future 
	i4le    440 
	i4le    1 # referenced by root key
	i4le    0 # descriptor length 

	# fill with empty cells
	for (( i=$(( (8192 - $(wc -c "$HIVEPATH" | cut -f 1 "-d ")) / 8 )); i > 0; i-- )); do
		i4lea 8 0;
	done
else
	echo "ERR: Hive path not specified";
fi

rm "$SHITFILE"