- name: hypsipyla
  hosts: hypsipyla.fi.muni.cz
  vars:
    dhcpcd: true
    nftables:
      nfs: false
      snmp: true
      pds_local: false
    snmpd:
      disks:
        - path: /
          free: '{{512 * 1024}}'

    ghc_primary_version: 8.6.5
    ghc_newest_version: 9.0.1
    ghc_versions:
      - 8.4.4
      - 8.6.5
      - 8.8.4
      - 8.10.4
      - 9.0.1
    cabal_version: "3.4"
    builtin_haddock_packages:
      - "base"
      - "directory"
      - "deepseq"
      - "mtl"
      - "transformers"
      - "stm"
      - "array"
      - "bytestring"
      - "containers"
      - "text"
      - "time"
      - "template-haskell"
      - "filepath"
      - "unix"
      - "process"
      - "parsec"
      - "pretty"
      - "xhtml"
      - "hpc"
    cabal_install:
      - "data-default-class"
      - "base-unicode-symbols"
    auto_install_ghc: false

  tasks:
    - fail:
        msg: possibly wrong server?
      when: ansible_distribution != 'Debian'

    - import_role:
        name: common_deb

    - import_role:
        name: ghc_deb

    - name: "Contextualization"
      systemd:
        name: '{{item}}'
        enabled: false
        state: stopped
      loop:
        - "one-context"
        - "one-context-local"

    - name: "Install SNMPd"
      apt:
        pkg:
          - snmpd

    - name: "Setup SNMPd"
      template:
        src: snmpd.conf.j2
        dest: /etc/snmp/snmpd.conf
      register: snmp_setup

    - name: "Restart SNMPd"
      service:
        name: snmpd
        state: '{{"restarted" if snmp_setup.changed else "started"}}'
        masked: false
        enabled: true

    - name: "Haskell user"
      user:
        name: "haskell"
        uid: 1000
        home: "/home/haskell"
        shell: "/usr/bin/bash"

    - name: "Install GHCs & cabal"
      apt:
        pkg:
          - 'ghc-{{ghc_primary_version}}'
          - 'ghc-{{ghc_newest_version}}'
          - 'cabal-install-{{cabal_version}}'

    - name: "Haskell setup (using GHC {{ghc_newest_version}})"
      block:
        - name: "Doc directory"
          file:
            path: "{{item}}"
            state: directory
          loop:
            - "/home/haskell/doc"
            - "/home/haskell/doc/pkg"
            - "/home/haskell/doc/ghc"

        - name: "Doc directory for GHC versions"
          file:
            path: "/home/haskell/doc/ghc/{{item}}"
            state: directory
          loop: '{{ghc_versions}}'

        - name: ".cabal exits?"
          stat:
            path: '/home/haskell/.cabal'
          register: dot_cabal

        - name: "Cabal update"
          command: "cabal update"
          when: not dot_cabal.stat.exists

        - name: "Cabal config"
          lineinfile:
            path: "/home/haskell/.cabal/config"
            line: '\1{{item.key}}: {{item.value}}'
            regex: '^(  )?(-- )?{{item.key}}:'
            backrefs: true
          loop:
            - key: "documentation"
              value: "True"
            - key: "html"
              value: "True"
            - key: "all"
              value: "True"
            - key: "hyperlink-source"
              value: "True"
            - key: "quickjump"
              value: "True"
            - key: "hoogle"
              value: "True"
            - key: "html-location"
              value: "https://haskell.fi.muni.cz/doc/$pkg-$version/"

        - name: "Is hoogle installed?"
          stat:
            path: "/home/haskell/.cabal/bin/hoogle"
          register: hoogle_bin

        - name: "Install hoogle"
          command: "cabal install hoogle --overwrite-policy=always"
          when: not hoogle_bin.stat.exists

      environment:
        PATH: "/opt/ghc/{{ghc_newest_version}}/bin/:/opt/ghc/bin:/home/haskell/.cabal/bin:{{ansible_env.PATH}}"
      become: true
      become_user: "haskell"

    - name: "Create hoogle database & docs (using GHC {{ghc_primary_version}})"
      block:
        - name: "Extract GHC docs"
          unarchive:
            creates: "/home/haskell/doc/ghc/{{item}}/libraries"
            dest: "/home/haskell/doc/ghc/{{item}}"
            src: "https://downloads.haskell.org/~ghc/{{item}}/docs/libraries.html.tar.xz"
            remote_src: true
          loop: '{{ghc_versions}}'

        - name: "Cabalized packages"
          command: "cabal install --lib {{cabal_install | join(' ')}}"

        - name: "Process and prepare docs"
          script:
            executable: bash
            chdir: "/home/haskell/doc/"
            cmd: "merge-haddocs ghc {{ghc_primary_version}}"

        - name: "Generate database"
          command: "hoogle generate --haddock=/home/haskell/doc/libraries {{builtin_haddock_packages | join(' ')}} {{cabal_install | join(' ')}}"
          environment:
            GHC_PACKAGE_PATH: '/opt/ghc/{{ghc_primary_version}}/lib/ghc-{{ghc_primary_version}}/package.conf.d:/home/haskell/.cabal/store/ghc-{{ghc_primary_version}}/package.db'

        - name: "Landing page git"
          git:
            dest: "/home/haskell/www"
            # note: this seems like a private token in a public repo and indeed
            # it is, however, there is actually nothing private about the
            # haskell.fi repo, it is just hidden in a private group, therefore,
            # it does not matter that we have the token saved here
            repo: "https://oauth2:1qz5SWyHJE3gGdes2r3X@gitlab.fi.muni.cz/ib015/haskell.fi"
            update: true
            recursive: true

      environment:
        PATH: "/opt/ghc/{{ghc_primary_version}}/bin/:/opt/ghc/bin:/home/haskell/.cabal/bin:{{ansible_env.PATH}}"
      become: true
      become_user: "haskell"

    - name: "Hoogle service file"
      copy:
        src: "hoogle.service"
        dest: "/etc/systemd/system"
      register: hoogle_service_file

    - name: "enable & start Hoogle service"
      systemd:
        name: "hoogle"
        state: 'restarted' # database generation can break the current instance
        enabled: true
        daemon_reload: '{{hoogle_service_file.changed}}'


    - name: "FJA user"
      user:
        name: "fja"
        uid: 1001
        home: "/home/fja"
        shell: "/usr/bin/bash"

    - name: "fjaweb dependencies"
      apt:
        pkg:
          - uwsgi
          - uwsgi-plugin-python3
          - python3-flask
          - python3-flaskext.wtf
          - antlr4
          - python3-antlr4
          - python3-mypy
          - python3-mypy-extensions

    - name: "extra fjaweb dependencies"
      pip:
        name:
          - Flask-Markdown
        executable: pip3

    - name: "fjaweb service files"
      copy:
        src: "{{item}}"
        dest: "/etc/systemd/system"
      loop:
        - "fjaweb.service"
        - "fjaweb.socket"
      register: fjaweb_service_file

    - name: "fjaweb git"
      git:
        dest: "/home/fja/eval"
        repo: "https://gitlab.fi.muni.cz/fja/eval.git"
        update: true
        recursive: true
      become: true
      become_user: fja
      register: fjaweb_update

    - name: "enable & start fjaweb socket"
      systemd:
        name: "fjaweb.socket"
        state: 'started'
        enabled: true
        daemon_reload: '{{fjaweb_service_file.changed}}'

    - name: "Stop fjaweb service if it was updated, socket will bring it up"
      systemd:
        name: "fjaweb.service"
        state: 'stopped'
        enabled: false
      when: '{{fjaweb_update.changed}}'

    - name: "install nginx & co"
      apt:
        pkg:
          - nginx
          - libnginx-mod-http-auth-pam
          - python3-certbot-nginx
          - certbot

    - name: "nginx PAM module for kerberos auth"
      copy:
        src: "pam.d/nginx"
        dest: "/etc/pam.d/nginx"

    - name: "nginx config"
      copy:
        src: "nginx.conf"
        dest: "/etc/nginx/nginx.conf"
      register: nginx_config

    - name: "remove nginx default site"
      file:
        path: "/etc/nginx/sites-enabled/default"
        state: absent
      register: nginx_def

    - name: "setup nginx sites"
      copy:
        src: "nginx/{{item}}"
        dest: "/etc/nginx/sites-enabled/{{item}}"
      register: nginx_sites
      loop:
        - 'hoogle'
        - 'haskell'
        - 'fja'
        - 'http'

    - name: "nginx service"
      systemd:
        name: "nginx"
        state: '{{"re" if nginx_config.changed or nginx_def.changed or nginx_sites.changed else ""}}started'
        enabled: true

    - name: "/srv/crs dir"
      file:
        state: directory
        path: "/srv/crs"

    - name: "dis-fi group"
      group:
        name: "dis-fi"
        gid: 1002

    - name: "dis-fi user"
      user:
        name: "dis-fi"
        group: "dis-fi"
        home: "/srv/crs/dis-fi"
        shell: "/usr/bin/bash"
        uid: 1002

    - name: "install npm"
      apt:
        pkg:
          - npm

    - name: "discord-irc NPM package"
      community.general.npm:
        name: "discord-irc"
        global: true
        production: true

    - name: "discord-irc service file"
      copy:
        src: "dis-fi.service"
        dest: "/etc/systemd/system"
      register: dis_fi_service

    - name: "discord-irc config"
      copy:
        src: "discord-irc-config.json"
        dest: "/srv/crs/dis-fi/config.json"
      register: dis_fi_config

    - name: "Enable dis-fi service"
      systemd:
        name: "dis-fi"
        enabled: true
        state: '{{"restarted" if dis_fi_service.changed or dis_fi_config.changed else "started"}}'
        daemon_reload: '{{dis_fi_service.changed}}'
