#!/bin/bash -efu

gray="$(echo -ne "\\033[0;37m")"
white="$(echo -ne "\\033[1;37m")"
cyan="$(echo -ne "\\033[1;36m")"

# usage message
usage() {
	echo "
Add user and configure hasher and gear for him/her
Usage:
$(basename ${0}) <user name>
Add and configure <user name>
$(basename ${0}) --help
Print this message
"
}

# Add string to file if this string is not in the file
# Usage: addifnot <string> <file>
addifnot() {
	if [ -z "$1" ] || [ -z "$2" ]; then
		echo "Error: Function addifnot requires two arguments: addifnot <string> <file>"
		return 1
	fi

	if [ -f "$2" ] && [ ! -w "$2" ]; then
		echo "Error: addifnot: File $2 is not writable"
		return 1
	fi

	grep $1 $2 >&/dev/null || echo $1 >> $2
}

if [ "$1" == "--help" ]; then
	usage
	exit 0
fi

# name for builder user
if [ $# -gt 0 ]; then
	USER=$1
else
	echo "Error: This script requires at least one argument."
	usage
	exit 1
fi

# ensure sudo user
if [ "$(whoami)" != "root" ]; then
	echo "Error: This script requires 'sudo' privileges in order to add user."
	exit 1
fi

ARCH="$(rpm --eval '%_host_cpu')"

# if useradd exit code 9 then this $USER already has a password
USRADDEX=0
useradd -m "$USER" || USRADDEX=$?
if [ $USRADDEX -eq 0 ]; then
	passwd "$USER"
else
	[ $USRADDEX -eq 9 ] || exit 1
fi

GROUP=$(id -g $USER)
HOME="$(cat /etc/passwd |grep ^${USER}: | cut -f6 -d :)"

# ~
[ -d "$HOME" ] || install -dm750 -o "$USER" -g "$GROUP" "$HOME"

# http://altlinux.org/tmpfs
TMP="/tmp/.private/$USER"

su - -c "git config --global user.email $USER@localhost" "$USER"
su - -c "git config --global user.name $USER" "$USER"

# rpm
[ -f "$HOME/.rpmmacros" ] && mv $HOME/.rpmmacros{,.save} &&
	chown $USER:$GROUP "$HOME/.rpmmacros.save"
cat > "$HOME/.rpmmacros" << EOF
%packager       $USER <$USER@altlinux.org>
%_target_cpu    $ARCH
%_tmppath       $TMP
%_sourcedir     %{_topsrcdir}/SOURCES/%name
EOF

chown $USER:$GROUP "$HOME/.rpmmacros"

# hasher
if [ "$ARCH" != i586 ] && [ "$ARCH" != x86_64 ] && [ "$ARCH" != e2k ]; then
	# Not enough space on tmpfs
	WORKDIR="$HOME/hasher"
else
	WORKDIR="$TMP/hasher"
	rm -fr "$HOME/hasher"
	ln -s "$WORKDIR" "$HOME/hasher"
fi

mkdir -p "$HOME/.hasher"
[ -f "$HOME/.hasher/config" ] && mv $HOME/.hasher/config{,.save}
cat > "$HOME/.hasher/config" << EOF
packager="\$(rpm --eval %packager)"
def_target=$ARCH
export GCC_USE_CCACHE=1
mkdir -p "$WORKDIR"
EOF

chown -R $USER:$GROUP "$HOME/.hasher"

# create apt.conf for supported ARCHES and BRANCHES
# use format: $BRANCH-$ARCH
create_apt_conf () {
	local PORTS=
	local SIGN=
	local BRANCH=$(echo "$1" | cut -f1 -d '-')
	local ARCH=$(echo "$1" | cut -f2 -d '-')
	local EXT_BRANCH=$(echo "$1" | cut -f3 -d '-')

	[ -n "$ARCH" ] || [ -n "$BRANCH" ] || exit 1
	[ -z "$EXT_BRANCH" ] || [ "$EXT_BRANCH" = port ] || exit 1

	[ "$EXT_BRANCH" = port ] && PORTS=1

	if [ "$BRANCH" = sisyphus ]; then
		BRANCH_PATH=Sisyphus
		SIGN='[alt]'
	else
		BRANCH_PATH="$BRANCH/branch"
		SIGN="[$BRANCH]"
	fi

	if [ -n "$PORTS" ]; then
		if [ "$BRANCH" = sisyphus ]; then
			BRANCH_PATH=ports/$ARCH/Sisyphus
		else
			BRANCH_PATH=ports/$ARCH/$BRANCH
		fi
		SIGN="[$BRANCH-$ARCH]"
	fi

	mkdir -p "$HOME/apt/lists/partial" \
		"$HOME/apt/cache/$BRANCH/$ARCH/archives/partial" \
		"$HOME/apt/cache/$BRANCH/noarch/archives/partial"

	cat > "$HOME/apt/apt.conf.$BRANCH.$ARCH" << EOF
Dir::Etc::main "/dev/null";
Dir::Etc::SourceParts "/var/empty";
Dir::Etc::SourceList "$HOME/apt/sources.list.$BRANCH.$ARCH";
Dir::State::lists "$HOME/apt/lists/";
Dir::Cache "$HOME/apt/cache/$BRANCH/$ARCH";
;Debug::pkgMarkInstall "true";
;Debug::pkgProblemResolver "true";
EOF

	cat > "$HOME/apt/sources.list.$BRANCH.$ARCH" << EOF
rpm-dir file://$HOME/hasher/repo $ARCH hasher
# Official repo (slow)
rpm $SIGN http://ftp.altlinux.org/pub/distributions/ALTLinux/$BRANCH_PATH $ARCH classic
rpm $SIGN http://ftp.altlinux.org/pub/distributions/ALTLinux/$BRANCH_PATH noarch classic
EOF

}

target_apt_confs="
sisyphus-x86_64
sisyphus-i586
sisyphus-aarch64
sisyphus-armh
sisyphus-ppc64le
sisyphus-mipsel-port
sisyphus-riscv64-port
p10-x86_64
p10-i586
p10-aarch64
p10-armh
p10-ppc64le
p9-x86_64
p9-i586
p9-aarch64
p9-armh
p9-ppc64le
p9-mipsel-port
"

for target_apt_conf in $target_apt_confs; do
	create_apt_conf "$target_apt_conf"
done

# setup mkimage-profiles settings
# add mkimage-profiles settings
mkdir -p $HOME/.mkimage
[ -f "$HOME/.mkimage/profiles.mk" ] && mv $HOME/.mkimage/profiles.mk{,.save}
cat > "$HOME/.mkimage/profiles.mk" << EOF
ifneq (,\$(BRANCH))
APTCONF = ~/apt/apt.conf.\$(BRANCH).\$(ARCH)
IMAGEDIR = ~/out/\$(BRANCH)/\$(shell date +%Y%m%d)
else
APTCONF = ~/apt/apt.conf.sisyphus.\$(ARCH)
IMAGEDIR = ~/out/sisyphus/\$(shell date +%Y%m%d)
endif

CLEAN = 1
DEBUG = 1
REPORT = 1
NO_SYMLINK = 1
#NICE = 1
#QUIET = 1
EOF

chown -R $USER:$GROUP "$HOME/apt" "$HOME/.mkimage"

# developer should feel comfortable, eh? ;-)
ZSHELL="/bin/zsh"
if [ -x "$ZSHELL" ]; then
	chsh -s "$ZSHELL" "$USER"
	install -m644 -o "$USER" -g "$GROUP" /dev/null "$HOME/.zshrc"
	cat >> "$HOME/.zsh_history" <<-EOF
	git clone git://git.altlinux.org/gears/m/mkimage-profiles.git && cd mkimage-profiles && make help/distro
	make -C /usr/share/mkimage-profiles grub.iso
	git clone git://git.altlinux.org/gears/h/hello.git && cd hello && gear-hsh
	EOF
	chown $USER:$GROUP "$HOME/.zsh_history"
fi

if type -t screen && [ ! -f "$HOME/.screenrc" ]; then
	cat >> "$HOME/.screenrc" <<-EOF
	caption always "%{+b rk}%H%{gk} |%c %{yk}%d.%m.%Y | %72=Load: %l %{wk}"
	defscrollback 1000
	EOF
	chown $USER:$GROUP "$HOME/.screenrc"
fi >&/dev/null

if [ ! -f "$HOME/.profile" ]; then
	cat >> "$HOME/.profile" <<-EOF
	clear
	cat << EOH
	Welcome to live builder environment!
	Here are some ALT package/image build tools prepared for you:
	* ${white}gear${gray}(1) -- see ${cyan}http://en.altlinux.org/gear${gray};
	* ${white}hsh${gray}(1)  -- see ${cyan}http://en.altlinux.org/hasher${gray};
	* ${white}mkimage${gray} -- see ${cyan}http://en.altlinux.org/mkimage${gray};
	* ${white}mkimage-profiles${gray} described in Russian at ${cyan}http://altlinux.org/m-p${gray}

	Examples (use right/middle mouse button to paste; see ~/hasher/repo/):
	* ${white}git clone git://git.altlinux.org/gears/h/hello.git && cd hello && gear-hsh${gray}
	* ${white}make -C /usr/share/mkimage-profiles grub.iso${gray}

	EOH
	EOF
	chown $USER:$GROUP "$HOME/.profile"
fi

# squashfs-tools 4.3+
addifnot "allowed_mountpoints=/proc" "/etc/hasher-priv/system" || exit 1

# need to increase the limits
addifnot "wlimit_time_elapsed=21600" "/etc/hasher-priv/system" || exit 1
addifnot "wlimit_time_idle=21600" "/etc/hasher-priv/system" || exit 1

# requisite
hasher-useradd "$USER"
