---
- hosts:
    - 127.0.0.1
  gather_facts: true
  become: true
  vars:
    pwnagotchi:
      hostname: "{{ lookup('env', 'PWN_HOSTNAME') | default('pwnagotchi', true) }}"
      version: "{{ lookup('env', 'PWN_VERSION') | default('pwnagotchi-torch', 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
        - bluetooth.service
        - ifup@wlan0.service
    packages:
      bettercap:
        # We will install bettercap from source
        # url: "https://github.com/jayofelony/bettercap/releases/download/2.32.1/bettercap-2.32.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.3/pwngrid_linux_aarch64_v1.10.3.zip"
      apt:
        downgrade:
          - libpcap0.8-dev_1.9.1-_arm64.deb
          - libpcap0.8_1.9.1-3_arm64.deb
          - libpcap-dev_1.9.1-3_arm64.deb
        hold:
          - libpcap-dev
          - libpcap0.8
          - libpcap0.8-dev
        remove:
          - raspberrypi-net-mods
          - dhcpcd5
          - triggerhappy
          - wpasupplicant
          - nfs-common
          - libraspberrypi0
          - libraspberrypi-dev
          - libraspberrypi-doc
          - libraspberrypi-bin
          - golang
        install:
          - bluez
          - raspberrypi-kernel-headers
          - git
          - libgmp3-dev
          - gawk
          - qpdf
          - bison
          - flex
          - make
          - autoconf
          - libtool
          - texinfo
          - gcc-arm-none-eabi
          - wl
          - libfl-dev
          - g++
          - xxd
          - aircrack-ng
          - time
          - rsync
          - vim
          - wget
          - screen
          - build-essential
          - dkms
          - python3-pip
          - python3-smbus
          - unzip
          - libopenmpi-dev
          - libatlas-base-dev
          - libelf-dev
          - libopenjp2-7
          - libtiff5
          - tcpdump
          - lsof
          - libgstreamer1.0-0
          - libavcodec58
          - libavformat58
          - libswscale5
          - libusb-1.0-0-dev
          - libnetfilter-queue-dev
          - libopenmpi3
          - dphys-swapfile
          - libdbus-1-dev
          - libdbus-glib-1-dev
          - liblapack-dev
          - libhdf5-dev
          - libc-ares-dev
          - libeigen3-dev
          - fonts-dejavu
          - fonts-dejavu-core
          - fonts-dejavu-extra
          - python3-pil
          - python3-smbus
          - libfuse-dev
          - libatlas-base-dev
          - libopenblas-dev
          - libblas-dev
          - bc
          - libgl1-mesa-glx
          - libncursesw5-dev
          - libssl-dev
          - libsqlite3-dev
          - tk-dev
          - libgdbm-dev
          - libc6-dev
          - libbz2-dev
          - libffi-dev
          - zlib1g-dev
          - fonts-freefont-ttf
          - fbi
          - python3-flask
          - python3-flask-cors
          - python3-flaskext.wtf
          - build-essential
          - libpcap-dev
          - libusb-1.0-0-dev
          - libnetfilter-queue-dev
  environment:
    ARCHFLAGS: "-arch armv8"

  tasks:
  - name: System details
    debug:
      msg="{{ item }}"
    with_items:
      - "{{ ansible_distribution }}"
      - "{{ ansible_distribution_version }}"
      - "{{ ansible_distribution_major_version }}"
      - "{{ ansible_architecture }}"
      - "{{ ansible_machine }}"

  - name: change hostname
    lineinfile:
      dest: /etc/hostname
      regexp: '^raspberrypi'
      line: "{{pwnagotchi.hostname}}"
      state: present
    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: configure dphys-swapfile
    lineinfile:
      path: /etc/dphys-swapfile
      regexp: "^CONF_SWAPSIZE=.*$"
      line: "CONF_SWAPSIZE=2048"

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

  - name: remove unnecessary apt packages
    become_user: root
    apt:
      name: "{{ packages.apt.remove }}"
      state: absent
      purge: yes

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

# Install nexmon to fix wireless scanning (takes 2.5G of space)
  - name: clone nexmon repository
    git:
      repo: https://github.com/DrSchottky/nexmon.git
      dest: /usr/local/src/nexmon
#      version: bfb3fe90c881498d7ee245b38f16722c1de26fa1
    register: nexmongit

  - name: make firmware
    shell: "source ./setup_env.sh && make"
    args:
      executable: /bin/bash
      chdir: /usr/local/src/nexmon/

  - name: choose the right kernel version (bcm43436b0)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
      backup: no
      regexp: "KERNEL_VERSION = .*$"
      replace: "KERNEL_VERSION = 6.1"

  - name: choose the right kernel release (variable) (bcm43436b0)
    lineinfile:
      dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
      insertafter: "DRIVER_FOLDER_NAME = .*$"
      line: "KERNEL_RELEASE = 6.1.21-v8+"

  - name: choose the right kernel release (replace string) (bcm43436b0)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/Makefile
      backup: no
      regexp: "shell uname -r"
      replace: "KERNEL_RELEASE"

  - name: make firmware patch (bcm43436b0)
    shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43436b0/9_88_4_65/nexmon/ && make && make install-firmware"
    args:
      executable: /bin/bash
      chdir: /usr/local/src/nexmon/

  - name: choose the right kernel version (bcm43430a1)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
      backup: no
      regexp: "KERNEL_VERSION = .*$"
      replace: "KERNEL_VERSION = 6.1"

  - name: choose the right kernel release (variable) (bcm43430a1)
    lineinfile:
      dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
      insertafter: "DRIVER_FOLDER_NAME = .*$"
      line: "KERNEL_RELEASE = 6.1.21-v8+"

  - name: choose the right kernel release (replace string) (bcm43430a1)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/Makefile
      backup: no
      regexp: "shell uname -r"
      replace: "KERNEL_RELEASE"

  - name: make firmware patch (bcm43430a1)
    shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make && make install-firmware"
    args:
      executable: /bin/bash
      chdir: /usr/local/src/nexmon/

  - name: choose the right kernel version (bcm43455c0)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
      backup: no
      regexp: "KERNEL_VERSION = .*$"
      replace: "KERNEL_VERSION = 6.1"

  - name: choose the right kernel release (variable) (bcm43455c0)
    lineinfile:
      dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
      insertafter: "DRIVER_FOLDER_NAME = .*$"
      line: "KERNEL_RELEASE = 6.1.21-v8+"

  - name: choose the right kernel release (replace string) (bcm43455c0)
    replace:
      dest: /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/Makefile
      backup: no
      regexp: "shell uname -r"
      replace: "KERNEL_RELEASE"

  - name: make firmware patch (bcm43455c0)
    shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43455c0/7_45_206/nexmon/ && make && make install-firmware"
    args:
      executable: /bin/bash
      chdir: /usr/local/src/nexmon/

  - name: copy modified driver (everyone but RPiZW)
    copy:
      src: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
      dest: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.orig

  - name: copy modified driver (everyone but RPiZW)
    copy:
      src: /usr/local/src/nexmon/patches/driver/brcmfmac_6.1.y-nexmon/brcmfmac.ko
      dest: /lib/modules/6.1.21-v8+/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko

  - name: ensure depmod runs on reboot to load modified driver (brcmfmac)
    lineinfile:
      dest: /etc/rc.local
      line: "/sbin/depmod -a"

  # To shrink the final image, remove the nexmon directory (takes 2.5G of space) post build and installation
  - name: Delete nexmon content & directory
    file:
      state: absent
      path: /usr/local/src/nexmon/

  - name: Creates custom plugin directory
    file:
      path: /usr/local/share/pwnagotchi/custom-plugins/
      state: directory

  - 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/jayofelony/pwnagotchi.git
      dest: /usr/local/src/pwnagotchi
    register: pwnagotchigit

  - name: create /usr/local/share/pwnagotchi/ folder
    file:
      path: /usr/local/share/pwnagotchi/
      state: directory

  - 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 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)

  # Install go-1.20.6
  - name: Install go-1.21
    unarchive:
      src: https://go.dev/dl/go1.21.1.linux-arm64.tar.gz
      dest: /usr/local
      remote_src: yes
    register: golang

  - name: Update .bashrc for go-1.21
    blockinfile:
      dest: /home/pi/.bashrc
      state: present
      block: |
        export GOPATH=$HOME/go
        export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
    when: golang.changed

  - name: download pwngrid
    git:
      repo: https://github.com/jayofelony/pwngrid.git
      dest: /usr/local/src/
    register: pwngrid

  - name: install pwngrid
    shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && make && sudo make install"
    args:
      executables: /bin/bash
      chdir: /usr/local/src/pwngrid
    when: pwngrid.changed

  - name: Install bettercap v2.32.1
    shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go env -w GO111MODULE=off && go get github.com/jayofelony/bettercap && cd $GOPATH/src/github.com/jayofelony/bettercap && make build && make install"
    args:
      executable: /bin/bash
    register: bettercap

  - name: clone bettercap caplets
    git:
      repo: https://github.com/jayofelony/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
    become_user: root
    file:
      path: /etc/pwnagotchi
      state: directory

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

  - name: create /etc/pwnagotchi/config.toml
    become_user: root
    copy:
      dest: /etc/pwnagotchi/config.toml
      content: |
        # Add your configuration overrides on this file any configuration changes done to default.toml will be lost!
        # Example:
        # ui.display.enabled = true
        # ui.display.type = "waveshare_2"
    when: not user_config.stat.exists

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

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

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

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

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

  - name: configure 01-motd
    become_user: root
    copy:
      dest: /etc/update-motd.d/01-motd
      content: |
        #!/bin/sh
        _hostname=$(hostname)
        _version=$(cut -d"'" -f2 < /usr/local/lib/python3.9/dist-packages/pwnagotchi/_version.py)
        echo
        echo "(◕‿‿◕) $_hostname"
        echo
        echo    "Hi! I'm a pwnagotchi $_version, please take good care of me!"
        echo    "Here are some basic things you need to know to raise me properly!"
        echo
        echo    "If you want to change my configuration, use /etc/pwnagotchi/config.toml"
        echo
        echo    "All the configuration options can be found on /etc/pwnagotchi/default.toml,"
        echo    "but don't change this file because I will recreate it every time I'm restarted!"
        echo
        echo    "I use oPwnGrid as my main API, you can check stats at https://opwngrid.xyz"
        echo
        echo    "I'm managed by systemd. Here are some basic commands."
        echo
        echo    "If you want to know what I'm doing, you can check my logs with the command"
        echo    "- pwnlog"
        echo    "- pwnver, to check the current version"
        echo    "- sudo pwnagotchi --donate, to see how you can donate to this project"
        echo    "- sudo pwnagotchi --check-update, to see if there is a new version available"
        echo
        echo    "If you want to know if I'm running, you can use"
        echo    "systemctl status pwnagotchi"
        echo
        echo    "You can restart me using"
        echo    "systemctl restart pwnagotchi"
        echo
        echo    "You learn more about me at https://pwnagotchi.ai/"
    when: hostname.changed

  - name: Add pwnlog alias
    lineinfile:
      dest: /home/pi/.bashrc
      line: "\nalias pwnlog='tail -f -n300 /var/log/pwn*.log | sed --unbuffered \"s/,[[:digit:]]\\{3\\}\\]//g\" | cut -d \" \" -f 2-'"
      insertafter: EOF

  - name: Add pwnlog alias
    lineinfile:
      dest: /home/pi/.bashrc
      line: "\nalias pwnver='python3 -c \"import pwnagotchi as p; print(p.__version__)\"'"
      insertafter: EOF

  - name: download old libpcap packages
    get_url:
      url: "http://ports.ubuntu.com/pool/main/libp/libpcap/{{ item }}"
      dest: /usr/local/src/
    with_items: "{{ packages.apt.downgrade }}"

  - name: install old libpcap packages
    become_user: root
    apt:
      deb: /usr/local/src/libpcap*
      args: allow-downgrades
    register: libpcap

  - name: add firmware packages to hold
    become_user: root
    dpkg_selections:
      name: "{{ item }}"
      selection: hold
    with_items: "{{ packages.apt.hold }}"
    when: libpcap.changed

  - name: clean apt cache
    become_user: root
    apt:
      autoclean: yes

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

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

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

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