---
- hosts:
    - 127.0.0.1
  become: yes
  vars:
    pwnagotchi:
      hostname: "{{ lookup('env', 'PWN_HOSTNAME') | default('pwnagotchi', true) }}"
      version: "{{ lookup('env', 'PWN_VERSION') | default('master', true) }}"
    system:
      boot_options:
        - "dtoverlay=dwc2"
        - "dtoverlay=spi1-3cs"
        - "dtparam=spi=on"
        - "dtparam=i2c_arm=on"
        - "dtparam=i2c1=on"
        - "gpu_mem=16"
      modules:
        - "i2c-dev"
    services:
      enable:
        - dphys-swapfile.service
        - pwnagotchi.service
        - bettercap.service
        - pwngrid-peer.service
        - epd-fuse.service
        - fstrim.timer
      disable:
        - apt-daily.timer
        - apt-daily.service
        - apt-daily-upgrade.timer
        - apt-daily-upgrade.service
        - wpa_supplicant.service
        - bluetooth.service
        - triggerhappy.service
        - ifup@wlan0.service
    packages:
      bettercap:
        url: "https://github.com/bettercap/bettercap/releases/download/v2.26.1/bettercap_linux_armhf_v2.26.1.zip"
        ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
      pwngrid:
        url: "https://github.com/evilsocket/pwngrid/releases/download/v1.10.1/pwngrid_linux_armhf_v1.10.1.zip"
      apt:
        hold:
          - firmware-atheros
          - firmware-brcm80211
          - firmware-libertas
          - firmware-misc-nonfree
          - firmware-realtek
        remove:
          - raspberrypi-net-mods
          - dhcpcd5
          - triggerhappy
          - wpa_supplicant
          - nfs-common
        install:
          - vim
          - screen
          - golang
          - git
          - build-essential
          - python3-pip
          - python3-mpi4py
          - python3-smbus
          - unzip
          - gawk
          - libopenmpi-dev
          - libatlas-base-dev
          - libjasper-dev
          - libqtgui4
          - libqt4-test
          - libopenjp2-7
          - libtiff5
          - tcpdump
          - lsof
          - libilmbase23
          - libopenexr23
          - libgstreamer1.0-0
          - libavcodec58
          - libavformat58
          - libswscale5
          - libpcap-dev
          - libusb-1.0-0-dev
          - libnetfilter-queue-dev
          - libopenmpi3
          - dphys-swapfile
          - kalipi-kernel
          - kalipi-bootloader
          - kalipi-re4son-firmware
          - kalipi-kernel-headers
          - libraspberrypi0
          - libraspberrypi-dev
          - libraspberrypi-doc
          - libraspberrypi-bin
          - fonts-dejavu
          - fonts-dejavu-core
          - fonts-dejavu-extra
          - python3-pil
          - python3-smbus
          - libfuse-dev
          - bc
          - fonts-freefont-ttf
          - fbi
          - python3-flask
          - python3-flask-cors
          - python3-flaskext.wtf

  tasks:
  - name: change hostname
    hostname:
      name: "{{pwnagotchi.hostname}}"
    when: lookup('file', '/etc/hostname') == "raspberrypi"
    register: hostname

  - name: add hostname to /etc/hosts
    lineinfile:
      dest: /etc/hosts
      regexp: '^127\.0\.1\.1[ \t]+raspberrypi'
      line: "127.0.1.1\t{{pwnagotchi.hostname}}"
      state: present
    when: hostname.changed

  - name: disable sap plugin for bluetooth.service
    lineinfile:
      dest: /lib/systemd/system/bluetooth.service
      regexp: '^ExecStart=/usr/lib/bluetooth/bluetoothd$'
      line: 'ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap'
      state: present

  - name: Add re4son-kernel repo key
    apt_key:
      url: https://re4son-kernel.com/keys/http/archive-key.asc
      state: present

  - name: Add re4son-kernel repository
    apt_repository:
      repo: deb http://http.re4son-kernel.com/re4son/ kali-pi main
      state: present

  - name: add firmware packages to hold
    dpkg_selections:
      name: "{{ item }}"
      selection: hold
    with_items: "{{ packages.apt.hold }}"

  - name: update apt package cache
    apt:
      update_cache: yes

  - name: remove unecessary apt packages
    apt:
      name: "{{ packages.apt.remove }}"
      state: absent
      purge: yes

  - name: upgrade apt distro
    apt:
      upgrade: dist

  - name: install packages
    apt:
      name: "{{ packages.apt.install }}"
      state: present

  - name: configure dphys-swapfile
    file:
      path: /etc/dphys-swapfile
      content: "CONF_SWAPSIZE=1024"

  - name: clone papirus repository
    git:
      repo: https://github.com/repaper/gratis.git
      dest: /usr/local/src/gratis
    register: gratisgit

  - name: build papirus service
    make:
      chdir: /usr/local/src/gratis
      target: rpi
      params:
        EPD_IO: epd_io.h
        PANEL_VERSION: 'V231_G2'
    when: gratisgit.changed

  - name: install papirus service
    make:
      chdir: /usr/local/src/gratis
      target: rpi-install
      params:
        EPD_IO: epd_io.h
        PANEL_VERSION: 'V231_G2'
    when: gratisgit.changed

  - name: configure papirus display size
    lineinfile:
      dest: /etc/default/epd-fuse
      regexp: "#EPD_SIZE=2.0"
      line: "EPD_SIZE=2.0"

  - name: collect python pip package list
    command: "pip3 list"
    register: pip_output

  - name: set python pip package facts
    set_fact:
      pip_packages: >
        {{ pip_packages | default({}) | combine( { item.split()[0]: item.split()[1] } ) }}
    with_items: "{{ pip_output.stdout_lines }}"

  - name: acquire python3 pip target
    command: "python3 -c 'import sys;print(sys.path.pop())'"
    register: pip_target

  - name: clone pwnagotchi repository
    git:
      repo: https://github.com/evilsocket/pwnagotchi.git
      dest: /usr/local/src/pwnagotchi
    register: pwnagotchigit

  - name: fetch pwnagotchi version
    set_fact:
      pwnagotchi_version: "{{ lookup('file', '/usr/local/src/pwnagotchi/pwnagotchi/_version.py') | regex_replace('.*__version__.*=.*''([0-9]+\\.[0-9]+\\.[0-9]+[A-Za-z0-9]*)''.*', '\\1') }}"

  - name: pwnagotchi version found
    debug:
      msg: "{{ pwnagotchi_version }}"

  - name: build pwnagotchi wheel
    command: "python3 setup.py sdist bdist_wheel"
    args:
      chdir: /usr/local/src/pwnagotchi
    when: (pwnagotchigit.changed) or (pip_packages['pwnagotchi'] is undefined) or (pip_packages['pwnagotchi'] != pwnagotchi_version)

  - name: install opencv-python
    pip:
      name: "https://www.piwheels.hostedpi.com/simple/opencv-python/opencv_python-3.4.3.18-cp37-cp37m-linux_armv6l.whl"
      extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
    when: (pip_packages['opencv-python'] is undefined) or (pip_packages['opencv-python'] != '3.4.3.18')

  - name: install tensorflow
    pip:
      name: "https://www.piwheels.hostedpi.com/simple/tensorflow/tensorflow-1.13.1-cp37-none-linux_armv6l.whl"
      extra_args: "--no-deps --no-cache-dir --platform=linux_armv6l --only-binary=:all: --target={{ pip_target.stdout }}"
    when: (pip_packages['tensorflow'] is undefined) or (pip_packages['tensorflow'] != '1.13.1')

  - name: install pwnagotchi wheel and dependencies
    pip:
      name: "{{ lookup('fileglob', '/usr/local/src/pwnagotchi/dist/pwnagotchi*.whl') }}"
      extra_args: "--no-cache-dir"
    when: (pwnagotchigit.changed) or (pip_packages['pwnagotchi'] is undefined) or (pip_packages['pwnagotchi'] != pwnagotchi_version)

  - name: download and install pwngrid
    unarchive:
      src: "{{ packages.pwngrid.url }}"
      dest: /usr/bin
      remote_src: yes
      mode: 0755

  - name: download and install bettercap
    unarchive:
      src: "{{ packages.bettercap.url }}"
      dest: /usr/bin
      remote_src: yes
      exclude:
        - README.md
        - LICENSE.md
      mode: 0755

  - name: clone bettercap caplets
    git:
      repo: https://github.com/bettercap/caplets.git
      dest: /tmp/caplets
    register: capletsgit

  - name: install bettercap caplets
    make:
      chdir: /tmp/caplets
      target: install
    when: capletsgit.changed

  - name: download and install bettercap ui
    unarchive:
      src: "{{ packages.bettercap.ui }}"
      dest: /usr/local/share/bettercap/
      remote_src: yes
      mode: 0755

  - name: add HDMI powersave to rc.local
    blockinfile:
      path: /etc/rc.local
      insertbefore: "exit 0"
      block: |
        if ! /opt/vc/bin/tvservice -s | egrep 'HDMI|DVI'; then
          /opt/vc/bin/tvservice -o
        fi

  - name: create /etc/pwnagotchi folder
    file:
      path: /etc/pwnagotchi
      state: directory

  - name: check if user configuration exists
    stat:
      path: /etc/pwnagotchi/config.yml
    register: user_config

  - name: create /etc/pwnagotchi/config.yml
    copy:
      dest: /etc/pwnagotchi/config.yml
      content: |
        # Add your configuration overrides on this file any configuration changes done to default.yml will be lost!
        # Example:
        #
        # ui:
        #   display:
        #     type: 'inkyphat'
        #     color: 'black'
        #
    when: not user_config.stat.exists

  - name: enable ssh on boot
    file:
      path: /boot/ssh
      state: touch

  - name: adjust /boot/config.txt
    lineinfile:
      dest: /boot/config.txt
      insertafter: EOF
      line: '{{ item }}'
    with_items: "{{system.boot_options}}"

  - name: adjust /etc/modules
    lineinfile:
      dest: /etc/modules
      insertafter: EOF
      line: '{{ item }}'
    with_items: "{{system.modules}}"

  - name: change root partition
    replace:
      dest: /boot/cmdline.txt
      backup: no
      regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+"
      replace: "root=/dev/mmcblk0p2"

  - name: configure /boot/cmdline.txt
    lineinfile:
      path: /boot/cmdline.txt
      backrefs: True
      state: present
      backup: no
      regexp: '(.*)$'
      line: '\1 modules-load=dwc2,g_ether'

  - name: configure motd
    copy:
      dest: /etc/motd
      content: |
        (◕‿‿◕) {{pwnagotchi.hostname}}

        Hi! I'm a pwnagotchi, please take good care of me!
        Here are some basic things you need to know to raise me properly!

        If you want to change my configuration, use /etc/pwnagotchi/config.yml

        All the configuration options can be found on /etc/pwnagotchi/default.yml,
        but don't change this file because I will recreate it every time I'm restarted!

        I'm managed by systemd. Here are some basic commands.

        If you want to know what I'm doing, you can check my logs with the command
        journalctl -fu pwnagotchi

        If you want to know if I'm running, you can use
        systemctl status pwnagotchi

        You can restart me using
        systemctl restart pwnagotchi

        But be aware I will go into MANUAL mode when restarted!
        You can put me back into AUTO mode using
        touch /root/.pwnagotchi-auto && systemctl restart pwnagotchi

        You learn more about me at https://pwnagotchi.ai/
    when: hostname.changed

  - name: clean apt cache
    apt:
      autoclean: yes

  - name: remove dependencies that are no longer required
    apt:
      autoremove: yes

  - name: enable services
    systemd:
      name: "{{ item }}"
      state: started
      enabled: yes
    with_items: "{{ services.enable }}"

  - name: disable unecessary services
    systemd:
      name: "{{ item }}"
      state: stopped
      enabled: no
    with_items: "{{ services.disable }}"

  - name: remove ssh keys
    file:
      state: absent
      path: "{{item}}"
    with_fileglob:
      - "/etc/ssh/ssh_host*_key*"

  handlers:
  - name: reload systemd services
    systemd:
      daemon_reload: yes
