#!/bin/bash

set -e

die() { echo "$1"; exit 1; }

# For empty dirs
shopt -s nullglob

[[ -n "$1" ]] || die 'Usage: loki_access_policy <user_config_path> <group_config_path>'
USER_CONFIG_PATH="$1"

[[ -n "$2" ]] || die 'Usage: loki_access_policy <user_config_path> <group_config_path>'
GROUP_CONFIG_PATH="$2"

# Create groups and set permissions
create_timus_group() {
    jq -c '.groups[]' "$1" | while read -r group; do
        group_name=$(echo "$group" | jq -r '.name')
        
        # Create group if it doesn't exist
        if ! getent group "$group_name" >/dev/null; then
            groupadd "$group_name"
            echo "Group $group_name created."
        else
            echo "Group $group_name already exists."
        fi
        
        # Apply read permissions
        echo "$group" | jq -r '.read_permission[]' | while read -r path; do
            setfacl -R -m g:"$group_name":rx "$path"
            setfacl -d -R -m g:"$group_name":rx "$path"
            echo "Read permission set for group $group_name on $path."
        done
    done
}

# Create users and assign to groups
create_timus_user() {
    user_json=$(cat "$1")
    
    # Extract user data from the JSON
    user_name=$(echo "$user_json" | jq -r '.name')
    programs_dir="/home/$user_name/programs"
    bash_profile="/home/$user_name/.bash_profile"

    # Create user if it doesn't exist
    if ! id -u "$user_name" >/dev/null 2>&1; then
        # /etc/skel/.bashrc is used to set up the aliases for the user
        useradd -m -s "/usr/bin/rbash" -p "$(openssl rand -base64 16)" "$user_name" 
        echo "User $user_name created."
    else
        usermod -s "/usr/bin/rbash" "$user_name"
        echo "User $user_name shell updated to /usr/bin/rbash."

        # Update .bashrc from /etc/skel/.bashrc to ensure aliases are available
        # This must run early, before any potentially failing operations
        bashrc_file="/home/$user_name/.bashrc"
        if [ -f /etc/skel/.bashrc ]; then
            cp /etc/skel/.bashrc "$bashrc_file"
            chown "$user_name":"$user_name" "$bashrc_file"
            chmod 644 "$bashrc_file"
            echo "Updated .bashrc for user $user_name from /etc/skel/.bashrc."
        fi
    fi

    # Add user to groups
    echo "$user_json" | jq -r '.groups[]' | while read -r group; do
        usermod -aG "$group" "$user_name"
        echo "User $user_name added to group $group."
    done
    
    # Set up authorized SSH keys
    ssh_key_location=$(echo "$user_json" | jq -r '.authorized_ssh_key_location')
    mkdir -p /home/"$user_name"/.ssh
    cp "$ssh_key_location" /home/"$user_name"/.ssh/authorized_keys
    chown -R "$user_name":"$user_name" /home/"$user_name"/.ssh
    chmod 700 /home/"$user_name"/.ssh
    chmod 600 /home/"$user_name"/.ssh/authorized_keys
    echo "SSH key for user $user_name set up from $ssh_key_location."

    # Reset the programs directory
    rm -rf "$programs_dir"
    mkdir -p "$programs_dir"
    chown "$user_name":"$user_name" "$programs_dir"

    # Handle .bash_profile: Remove immutable flag if set
    if lsattr "$bash_profile" 2>/dev/null | grep -q 'i'; then
        chattr -i "$bash_profile"
    fi
    
    # Reset PATH in .bash_profile
    cat <<EOF > "$bash_profile"
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

# User specific environment and startup programs
readonly PATH=\$HOME/programs
export PATH
EOF
    chown "$user_name":"$user_name" "$bash_profile"
    chmod 644 "$bash_profile"

    # Set .bash_profile as immutable
    chattr +i "$bash_profile"

    # Set up allowed commands - create symlinks in programs directory
    echo "$user_json" | jq -c '.allowed_commands[]' | while read -r command; do
        cmd_path=$(echo "$command" | jq -r '.command')
        cmd_basename=$(basename "$cmd_path")
        link_path="$programs_dir/$cmd_basename"

        # Link command to user-specific directory
        ln -sf "$cmd_path" "$link_path"
    done

    echo "Allowed commands for user $user_name set up."
}

for GROUP_CONFIG in "$GROUP_CONFIG_PATH"/*.json; do
    create_timus_group "$GROUP_CONFIG"
done

for USER_CONFIG in "$USER_CONFIG_PATH"/*.json; do
    create_timus_user "$USER_CONFIG"
done

systemctl restart sshd