#!/bin/sh

# We're using chroot and mount, we need root
if [ "$(id -u)" -ne "0" ]; then
    echo "You must be root to use this command"
    exit 1
fi

# Initialize options
opt_command=0
opt_home=0
opt_network=0
#opt_save=0
opt_size=0
opt_tmp=0
opt_type=0
COMMAND=""
#SAVE=""
#SAVE_DIRS="root-cow"
SIZE=0
TYPE="ext4"

# Parse parameters
for arg in "$@"; do
    [ "$arg" = "$0" ] && continue
    [ "$opt_command" -eq "1" ] && COMMAND="$arg" && opt_command=0 && continue
#    [ "$opt_save" -eq "1" ] && SAVE="$arg" && opt_save=0 && continue
    [ "$opt_size" -eq "1" ] && SIZE="$arg" && opt_size=0 && continue
    [ "$opt_type" -eq "1" ] && TYPE="$arg" && opt_type=0 && continue

    case $arg in
        -c|-command|--command)
            opt_command=1
        ;;

        -h|-home|--home)
            opt_home=1
        ;;

        -n|-network|--network)
            opt_network=1
        ;;

        -s|-size|--size)
            opt_size=1
        ;;

        -t|-type|--type)
            opt_type=1
        ;;

        -T|-tmp|--tmp)
            opt_tmp=1
        ;;

        -help|--help|*)
            echo "Usage: $0 [OPTION]... [COMMAND]
Start a new container.
If COMMAND is passed, then it'll be started in the container.
Options:
  -c, --command     Run specific command in container (command as argument)
  -h, --home        Use real home directory instead of copy-on-write
  -n, --network     Enable networking in the container
  -s, --size        Storage size in MB (default: 2 on ext4, 50% of RAM on tmpfs)
  -t, --type        Storage type. Supported values: ext4, tmpfs (default: ext4)
  -T, --tmp         Use real tmpfs directory instead of copy-on-write

For X to work on >= 2.6.36, you need one of -n (network) or -T (real /tmp).
For older versions of the kernel, only -n (network) will work."
            exit 1
        ;;
    esac
done

#if [ -n "$SAVE" ]; then
#    echo "Save target $SAVE already exists."
#    exit 1
#fi

[ "$opt_home" -eq "1" ] && echo "/home is bind-mounted, changes will affect your real /home"
[ "$opt_tmp" -eq "1" ] && echo "/tmp is bind-mounted, changes will affect your real /tmp"
[ "$opt_network" -eq "1" ] && echo "Starting with network support" && NETWORK="network" || NETWORK="nonetwork"

# Check if /home is a separate partition
if [ -z "$(grep ' /home ' /proc/mounts)" ]; then
    if [ "$TYPE" = "ext4" ]; then
        echo "/home needs to be on a separate partition for ext4 storage type. Falling back to tmpfs"
        TYPE="tmpfs"
    fi
fi

echo "Using $TYPE for copy-on-write storage"

# Prepare storage
mkdir -p $HOME/.arkose
arkose_path=$(mktemp -d --tmpdir=$HOME/.arkose/)
case "$TYPE" in
    ext4)
        if [ "$SIZE" = "0" ]; then
            SIZE="2048"
        fi
        IMG_FILE=$(mktemp -u --tmpdir=$HOME/.arkose/)
        dd if=/dev/zero of=$IMG_FILE bs=1M count=0 seek=$SIZE 2>/dev/zero
        mkfs.ext4 -O ^has_journal -F -q $IMG_FILE
        mount -t ext4 -o loop $IMG_FILE $arkose_path
    ;;
    tmpfs)
        TMPFS_ARG=""
        if [ "$SIZE" != "0" ]; then
            TMPFS_ARG="-o size=${SIZE}M"
        fi
        mount -t tmpfs none $arkose_path $TMPFS_ARG
    ;;
    *)
        echo "Invalid storage type: $TYPE"
        exit 1
    ;;
esac

# Create structure for root filesystem
mkdir $arkose_path/root-cow
mkdir $arkose_path/target

# Mount root filesystem
mount -t aufs none $arkose_path/target -o br=$arkose_path/root-cow:/

if [ "$opt_tmp" -eq "1" ]; then
    # Bind-mount /tmp
    mount -o bind /tmp $arkose_path/target/tmp
fi

# Mount home directory (aufs or bind-mount)
if [ "$opt_home" -eq "1" ]; then
    mount -o bind -t none /home $arkose_path/target/home
else
#    SAVE_DIRS="$SAVE_DIRS home-cow"
    mkdir $arkose_path/home-cow
    mount -t aufs none $arkose_path/target/home -o br=$arkose_path/home-cow:/home
fi

# Starting the actual sandbox
arkose-helper $NETWORK $arkose_path/target $COMMAND

# Unmount copy-on-write
umount $arkose_path/target/home
if [ "$opt_tmp" -eq "1" ]; then
    umount $arkose_path/target/tmp
fi
umount $arkose_path/target

## Save container
#if [ -n "$SAVE" ]; then
#    echo "Saving container in $HOME/.arkose/archive/$SAVE.tar.gz"
#    mkdir -p $HOME/.arkose/archive/
#    tar -zcf $HOME/.arkose/archive/$SAVE.tar.gz -C $arkose_path $SAVE_DIRS
#fi

# Unmounting storage
umount $arkose_path
rmdir $arkose_path
if [ -n "$IMG_FILE" ] && [ -f "$IMG_FILE" ]; then
    rm $IMG_FILE
fi
