---
# Create users for all machines.

## Variables ##

- name: General | Account Management | Users | Use BASH (Default)
  set_fact:
    user_shell: "{{ bash_exec.stdout }}"

- name: General | Account Management | Users | Allow BASH (Arch)
  lineinfile:
    path: /etc/shells
    regexp: "{{ bash_exec.stdout }}"
    line: "{{ bash_exec.stdout }}"
    insertbefore: "# End of file"
    backup: yes
    create: no
    state: present
  when: ansible_distribution == "Archlinux"
  
#- name: General | Account Management | Users | Use ZSH (Arch+Manjaro)
#  set_fact:
#    user_shell: "{{ zsh_exec.stdout }}"
#  when: ansible_distribution == "Archlinux"
#
#- name: General | Account Management | Users | Allow ZSH (Arch)
#  lineinfile:
#    path: /etc/shells
#    regexp: "{{ zsh_exec.stdout }}"
#    line: "{{ zsh_exec.stdout }}"
#    insertbefore: "# End of file"
#    backup: yes
#    create: no
#    state: present
#  when: ansible_distribution == "Archlinux"


## Root ##

- name: General | Account Management | Users | Root
  user:
    name: root
    shell: "{{ bash_exec.stdout }}"
    create_home: yes
    generate_ssh_key: yes
  register: user_root


## Scheduler ##

- name: General | Account Management | Users | Ansible
  user:
    name: ansible
    comment: Ansible
    system: yes
  register: user_ansible


## Superuser ##

- name: General | Account Management | Users | Hyperling
  user:
    name: "{{ user }}"
    comment: "{{ user_desc }}"
    groups: 
      - sudo
      - video
      - render
    append: yes
    shell: "{{ user_shell }}"
    create_home: yes
    generate_ssh_key: yes
  register: user_user

- name: General | Account Management | Users | Hyperling | Test Logging In
  shell: "echo SUCCESS"
  args:
    executable: "{{ user_shell }}"
  become_user: "{{ user }}"


## Folders ##

- name: General | Account Management | Users | Folders | Root | Create bin, Downloads, TRASH
  file: 
    path: "{{ item }}"
    state: directory
    mode: '0755'
  loop:
    - "{{ user_root.home }}/bin"
    - "{{ user_root.home }}/Downloads"
    - "{{ user_root.home }}/TRASH"
  when: user_root.home != ""

- name: General | Account Management | Users | Folders | Hyperling | Create bin, LBRY, TRASH
  file: 
    path: "{{ item }}"
    state: directory
    mode: '0755'
  loop:
    - "{{ user_user.home }}/bin"
    - "{{ user_user.home }}/LBRY"
    - "{{ user_user.home }}/TRASH"
    - "{{ user_user.home }}/Downloads"
    - "{{ user_user.home }}/Reports"
  become_user: "{{ user }}"
  when: user_user.home != ""

- name: General | Account Management | Users | Folders | Home Directories 700
  shell: "chmod 700 {{ user_user.home }}/../*"


## Files ##

- name: General | Account Management | Users | Files | RC Variables
  set_fact:
    alias_cp: alias cp='cp -v'
    alias_mv: alias mv='mv -v'
    alias_rm: alias rm='echo "Use mv ~/TRASH/ instead!"'
    alias_clean_dir: alias clean-dir='mv * ~/TRASH/'
    alias_clean_trash: alias clean-trash='sh -c "rm -rfv ~/TRASH/*"'
    path_additions: export PATH="~/bin:$PATH"
    function_wttr: |
      function weather() {
        # 20210301 - Someone showed me an awesome weather API! Had to implement it!
        if [[ "$1" == "-"* || $2 != "" ]]; then
          echo 'USAGE: weather [location]
        Any "-" paramaters call the usage since this function does not take any options.
        Location is optional since the API can determine your connection'"'"'s location.
        Useful location types:
          $zip_code              | Ex: 12345
          $city,$state           | Ex: Austin,Texas
          @$domain_dot_extension | Ex: @github.com
          ~$special_location     | Ex: ~Manitou Incline
        Full documentation: https://github.com/chubin/wttr.in'
          return 1
        fi
        curl "https://wttr.in/${1//\ /+}"
      }
    PS1: export PS1='[\u@\h \w]\$ '
    remount: alias remount='sudo umount /mnt/*; sudo umount /mnt/*/*; sudo mount -a; echo -e "\nRemount completed!"; mount | grep /mnt'
    update: |
      function update() {
        PROG=$FUNCNAME
        usage="Usage: $PROG [-y]
        $PROG is used to run all the system's package manager commands 
          in one swoop. Flow stops if any command returns a failure code.
          The hope is to run something as easy as 'pacman -Syyu'.
        -y : Assume yes to any prompts."

        unset OPTIND
        unset accept
        while getopts ":hy" opt; do
            case $opt in
              h) echo -e "$usage"
                  return 0 ;;
              y) accept="-y" ;;
              *) echo "ERROR: -$OPTARG is not a recognized option."
                  echo -e "$usage"
                  return 1 ;;
            esac
        done

        {{ update_package_manager }}
        {{ update_flatpak }}
        return 0

        echo "ERROR: $PROG experienced a problem and has aborted."
        return 1
      }
    sync: alias sync='date && echo "Syncing!" && sync && date'
    editor: export EDITOR='vi'
    init_aliases: |
      alias init-video='mkdir -v raw; mkdir -v exports; cp ~/Templates/*video* ./' 
      alias init-vid=init-video
      alias init-program='echo -e "#!/bin/bash\n# `date +%Y-%m-%d` by Hyperling\n# REASON\n\nexit 0\n"'
      alias init-prog=init-program
    bye: |
      alias bye="{{ shutdown_command }}"
      alias goodbye="update -y && bye"
    metasploit: |
      alias metasploit="msfconsole"
      alias hax="metasploit"
    show_config: |
      alias show-config-gen="cat {{ gen_file }}"
      alias show-config-wrk="cat {{ wrk_file }}"
      alias show-config-mnr="cat {{ mnr_file }}"
      alias show-config-srv="cat {{ srv_file }}"
      alias show-config-all="show-config-gen && echo '' && show-config-wrk && echo '' && show-config-mnr && echo '' && show-config-srv"
      alias show-config="show-config-all"
    edit_config: |
      alias edit-config-gen="sudo $EDITOR {{ gen_file }}"
      alias edit-config-wrk="sudo $EDITOR {{ wrk_file }}"
      alias edit-config-mnr="sudo $EDITOR {{ mnr_file }}"
      alias edit-config-srv="sudo $EDITOR {{ srv_file }}"
    function_check_trash: |
      function check-trash() {
        unset OPTIND
        unset clean
        unset network
        while (( $# > 0 )); do
          case $1 in
            -c | -y | --clean ) clean="Y" ;;
            -n | -net | --network ) network="Y" ;;
            * ) echo "
            ERROR: Option '$1' with value '$2' not recognized.
              $PROG [-c|-clean|--clean|-y] [-n|-net|--network]
            " 
            return 1
          esac
          shift
        done
        echo "clean=$clean"
        echo "network=$network"
        echo "Grabbing sudo permissions..."
        sudo echo "Success! Starting search..."
        function dirs_to_check {
          echo "/root"
          echo "/home"
        }
        dirs_to_check | while read dir; do 
          echo "Checking $dir..."
          sudo find $dir -name TRASH | while read trash; do 
            if [[ "$trash" != "" && `sudo ls $trash` ]]; then
              echo "Found $trash with contents:"
              sudo ls -lh $trash
              if [[ "$clean" == "Y" ]]; then
                echo "Cleaning trash..."
                sudo sh -c "rm -rfv $trash/*"
              fi
            fi
          done 
        done
        if [[ "$network" == "Y" ]]; then
          function network_to_check {
            find /mnt -maxdepth 1 -mindepth 1 
          }
          network_to_check | while read dir; do 
            echo "Checking $dir..."
            sudo find $dir -name TRASH | while read trash; do 
              if [[ "$trash" != "" && `sudo ls $trash` ]]; then
                echo "Found $trash with contents:"
                sudo ls -lh $trash
                if [[ "$clean" == "Y" ]]; then
                  echo "Cleaning trash..."
                  sudo sh -c "rm -rfv $trash/*"
                fi
              fi
            done 
          done
        fi
        echo "Checking but not cleaning /var/mail..."
        du -ha /var/mail | sort -h
        return 0
      }
      alias check_trash="check-trash"
    function_clean: |
      function clean() {
        sudo df -h
        check-trash --clean
        sudo df -h
      }
    function_flatpak_usage: |
      function flatpak-usage() {
        flatpak list --columns=application | while read app; do
          size=`flatpak info -s $app 2>/dev/null`
          if [[ ! -z $size ]]; then
            mb=$(( size / (1000*1000) ))
            echo "${mb} MB, $size Bytes, $app"
          fi
        done | sort -n
      }
    function_flatpak_purge: |
      function flatpak-purge() {
        flatpak remove --all --delete-data &&
        flatpak repair &&
        echo "Finished purging all Flatpak apps. Executable may still need uninstalled." &&
        return
        echo "ERROR: Something went wrong while removing Flatpak apps!"
      }
    alias_vim: alias vi=vim

- name: General | Account Management | Users | Files | Common Variable
  set_fact:
    rc_common: |
      {{ path_additions }}
      {{ alias_cp }}
      {{ alias_mv }}
      {{ alias_rm }}
      {{ alias_clean_dir }}
      {{ alias_clean_trash }}
      {{ function_wttr }}
      {{ PS1 }}
      {{ remount }}
      {{ update }}
      {{ sync }}
      {{ editor }}
      {{ init_aliases }}
      {{ bye }}
      {{ metasploit }}
      {{ show_config }}
      {{ edit_config }}
      {{ function_check_trash }}
      {{ function_clean }}
      {{ function_flatpak_usage }}
      {{ function_flatpak_purge }}
      {{ alias_vim }}

- name: General | Account Management | Users | Files | .bashrc
  blockinfile:
    path: "{{ item }}/.bashrc"
    block: |
      {{ rc_common }}
      [[ $(whoami) != "root" ]] && echo "`date` - Ansible .bashrc preferences loaded successfully!"
    marker: '# {mark} MANAGED BY ANSIBLE | Aliases'
    state: present
    create: yes
    backup: yes
  loop:
    - "{{ user_root.home }}"
    - "{{ user_user.home }}"
  ignore_errors: yes
  when: user_root.home != "" and user_user.home != ""

- name: General | Account Management | Users | Files | .zshrc
  blockinfile:
    path: "{{ item }}/.zshrc"
    block: |
      {{ rc_common }}
      [[ $(whoami) != "root" ]] && echo "`date` - Ansible .zshrc preferences loaded successfully!"
    marker: '# {mark} MANAGED BY ANSIBLE | Aliases'
    state: present
    create: yes
    backup: yes
  loop:
    - "{{ user_root.home }}"
    - "{{ user_user.home }}"
  ignore_errors: yes
  when: user_root.home != "" and user_user.home != ""

- name: General | Account Management | Users | Files | .vimrc
  blockinfile:
    path: "{{ item }}/.vimrc"
    block: |
      " Turn off syntax, flashy lights, etc. Make VIM into a basic editor.
      syntax off
      set nohlsearch
      set noautoindent noautowrite noshowmatch wrapmargin=0 report=1 ts=3
      set ignorecase

      " Turn off auto-commenting.
      autocmd Filetype * set fo-=c fo-=r fo-=o

      " qq shortcut for immediately exiting all files without saving.
      nnoremap qq :qa!<cr>
    marker: '" {mark} MANAGED BY ANSIBLE | vimrc'
    state: present
    create: yes
    backup: yes
  loop:
    - "{{ user_root.home }}"
    - "{{ user_user.home }}"
  ignore_errors: yes
  when: user_root.home != "" and user_user.home != ""