name: "Build and test LXD image"
on:
  workflow_call:
    inputs:
      git_ref:
        required: true
        type: string
    outputs:
      artifact_name:
        value: "${{ jobs.build-current.outputs.artifact_name }}"
      artifact_file:
        value: "${{ jobs.build-current.outputs.artifact_file }}"
  push:
    branches:
      - "**"
  pull_request:
    branches:
      - master
      - devel
      - release/*

jobs:
  build-current:
    runs-on: ubuntu-20.04
    outputs:
      artifact_name: "${{ env.ARTIFACT_NAME }}"
      artifact_file: "${{ steps.pack-lxd.outputs.artifact_file }}"
    env:
      VERSION: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
      ARTIFACT_NAME: "${{ github.run_id }}-lxd-image"
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: "${{ env.VERSION }}"
      - uses: whywaita/setup-lxd@v1
        with:
          lxd_version: latest/stable

#      - name: Fix LXD
#        run: |
#          ip address
#          ip route list
#          lxc profile create network
#          cat <<EOF | lxc profile edit network
#          devices:
#            eth0:
#              name: eth0
#              parent: lxdbr0
#              nictype: bridged
#              type: nic
#          EOF
#          ip route list
#          ifconfig lxdbr0

      - name: Debug LXD
        run: |
          lxc version
          lxc network set lxdbr0 ipv4.nat true
          lxc network list
      - name: Build LXD image
        run: |
          ./build/build-LXD.sh
      - name: Pack LXD image
        id: pack-lxd
        run: |
          . ./build/buildlib.sh
          ARTIFACT_FILE="NextCloudPi_LXD_${VERSION//\//_}"
          lxc image export -q ncp/"${version}" "output/${ARTIFACT_FILE}"
          echo "artifact_file=${ARTIFACT_FILE}.tar.gz" >> $GITHUB_OUTPUT
      - name: upload LXD image to artifact store
        uses: actions/upload-artifact@v3
        with:
          name: "${{ env.ARTIFACT_NAME }}"
          path: "output/${{ steps.pack-lxd.outputs.artifact_file }}"
          if-no-files-found: error

  build-previous:
    runs-on: ubuntu-20.04
    outputs:
      artifact_name: "${{ env.ARTIFACT_NAME }}"
      artifact_file: "${{ steps.pack-lxd.outputs.artifact_file }}"
      previous_version: "${{ steps.checkout_previous_version.outputs.previous_version }}"
    env:
      VERSION: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
      ARTIFACT_NAME: "${{ github.run_id }}-lxd-image-previous"
      LXD_EXTRA_PROFILE: network
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: "${{ env.VERSION }}"
          fetch-depth: 0
      - name: Checkout previous release
        id: checkout_previous_version
        shell: bash
        run: |
          set -e
          if [[ -n "${{ github.base_ref }}" ]]
          then
            version="${{ github.base_ref }}"
          elif [[ "${{ env.VERSION }}" == "refs/heads/devel" ]]
          then
            version="master"
          else
            if [[ "${{ github.ref_type }}" != "tag" ]] || ! git describe --tags > /dev/null
            then
              git fetch -fu --tags origin ${{ env.VERSION }}:${{ env.VERSION }}
            fi
            version="$(git describe --tags)"
            [[ "$version" =~ .*-.*-.* ]] || {
              git checkout HEAD~1
              version="$(git describe --tags)"
            }
            version="${version%-*-*}"
          fi
          echo "Previous version is '$version'"
          git checkout "$version"
          echo "VERSION=$version" >> "$GITHUB_ENV"
          echo "previous_version=${version}" >> $GITHUB_OUTPUT
      - uses: whywaita/setup-lxd@v1
        with:
          lxd_version: latest/stable
      - name: Fix LXD
        run: |
          lxc profile create network
          cat <<EOF | lxc profile edit network
          devices:
            eth0:
              name: eth0
              parent: lxdbr0
              nictype: bridged
              type: nic
          EOF
      - name: Build LXD image
        run: |
          ./build/build-LXD.sh
      - name: Pack LXD image
        id: pack-lxd
        run: |
          . ./build/buildlib.sh
          ARTIFACT_FILE="NextCloudPi_LXD_${VERSION//\//_}"
          lxc image export -q ncp/"${version}" "output/${ARTIFACT_FILE}"
          echo "artifact_file=${ARTIFACT_FILE}.tar.gz" >> $GITHUB_OUTPUT
      - name: upload LXD image to artifact store
        uses: actions/upload-artifact@v3
        with:
          name: "${{ env.ARTIFACT_NAME }}"
          path: "output/${{ steps.pack-lxd.outputs.artifact_file }}"
          if-no-files-found: error

  update-previous:
    needs:
      - build-previous
    runs-on: ubuntu-20.04
    outputs:
      artifact_name: "${{ env.ARTIFACT_NAME }}"
      artifact_file: "${{ steps.pack-lxd.outputs.artifact_file }}"
    env:
      VERSION: "${{ inputs.git_ref || github.ref }}"
      ARTIFACT_NAME: "${{ github.run_id }}-lxd-image-updated"
    steps:
      - uses: whywaita/setup-lxd@v1
        with:
          lxd_version: latest/stable
      - name: Fix LXD
        run: |
          lxc profile create network
          cat <<EOF | lxc profile edit network
          devices:
            eth0:
              name: eth0
              parent: lxdbr0
              nictype: bridged
              type: nic
          EOF
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: "${{ env.VERSION }}"
      - name: download LXD image from artifact store
        uses: actions/download-artifact@v3
        with:
          name: ${{ needs.build-previous.outputs.artifact_name }}
      - name: Launch ncp container
        run: |
          set -x
          lxc delete -q -f ncp || true
          lxc image import -q "./${{ needs.build-previous.outputs.artifact_file }}" --alias "ncp/update"
          systemd-run --user --scope -p "Delegate=yes" lxc launch -q "ncp/update" ncp
          lxc exec ncp -- bash -c 'while [ "$(systemctl is-system-running 2>/dev/null)" != "running" ] && [ "$(systemctl is-system-running 2>/dev/null)" != "degraded" ]; do :; done'
          sleep 30
          ip="$(lxc list -c n4 -f csv | grep '^ncp' | cut -d ',' -f2)"
          ip="${ip/% *}"
          echo "${ip} nextcloudpi.local" | sudo tee /etc/hosts

      - name: Update ncp
        run: |
          set -ex
          BRANCH="${VERSION/refs\/heads\//}"
          BRANCH="${BRANCH/refs\/tags\//}"
          if [[ "$BRANCH" =~ "refs/pull/"* ]]
          then
            UPDATE_ARGS=("${{ github.base_ref }}" "$VERSION") 
          else
            UPDATE_ARGS=("$BRANCH")
          fi
          echo "VERSION=${VERSION}" >> "$GITHUB_ENV"
          echo "Running update ${{ needs.build-previous.outputs.previous_version }} -> ${VERSION}"
          
          current_nc_version="$(lxc exec ncp -- ncc status | grep "version:" | awk '{ print $3 }')"
          latest_nc_version="$(cat etc/ncp.cfg | jq -r '.nextcloud_version')"
          
          lxc exec ncp -- bash -c "DBG=x ncp-update ${UPDATE_ARGS[*]}"
          lxc exec ncp -- /usr/local/bin/ncc status
          
          if [[ "$current_nc_version" =~ "$latest_nc_version".* ]]
          then
            echo "Nextcloud is up to date - skipping NC update test."
          else
            lxc exec ncp -- bash -c "DBG=x ncp-update-nc ${latest_nc_version?}"
          fi
          
          lxc stop ncp
      - name: Pack LXD image
        id: pack-lxd
        run: |
          set -x
          . ./build/buildlib.sh
          ARTIFACT_FILE="NextCloudPi_LXD_${VERSION//\//_}"
          lxc publish -q ncp -f --alias "ncp/updated"
          mkdir -p output
          lxc image export -q "ncp/updated" "output/${ARTIFACT_FILE}"
          echo "artifact_file=${ARTIFACT_FILE}.tar.gz" >> $GITHUB_OUTPUT
      - name: upload LXD image to artifact store
        uses: actions/upload-artifact@v3
        with:
          name: "${{ env.ARTIFACT_NAME }}"
          path: "output/${{ steps.pack-lxd.outputs.artifact_file }}"
          if-no-files-found: error

  test-fresh-install:
    needs:
      - build-current
    runs-on: ubuntu-20.04
    env:
      VERSION: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
      ARTIFACT_NAME: ${{ needs.build-current.outputs.artifact_name }}
      ARTIFACT_FILE: ${{ needs.build-current.outputs.artifact_file }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: "${{ env.VERSION }}"
      - uses: whywaita/setup-lxd@v1
        with:
          lxd_version: latest/stable
      - name: Fix LXD
        run: |
          lxc profile create network
          cat <<EOF | lxc profile edit network
          devices:
            eth0:
              name: eth0
              network: lxdbr0
              type: nic
          EOF
      - name: Setup Firefox
        uses: browser-actions/setup-firefox@latest
      - name: Setup GeckoDriver
        uses: ChlodAlejandro/setup-geckodriver@latest
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Selenium
        run: pip install selenium
      - name: download LXD image from artifact store
        uses: actions/download-artifact@v3
        with:
          name: ${{ env.ARTIFACT_NAME }}
      - name: Launch ncp container
        run: |
          set -x
          lxc delete -q -f ncp || true
          lxc image import -q "./${ARTIFACT_FILE?}" --alias "ncp/test"
          systemd-run --user --scope -p "Delegate=yes" lxc launch -q "ncp/test" ncp
          lxc exec ncp -- bash -c 'while [ "$(systemctl is-system-running 2>/dev/null)" != "running" ] && [ "$(systemctl is-system-running 2>/dev/null)" != "degraded" ]; do :; done'
          sleep 30
          ip="$(lxc list -c n4 -f csv | grep '^ncp' | cut -d ',' -f2)"
          ip="${ip/% *}"
          echo "${ip} nextcloudpi.local" | sudo tee /etc/hosts
      - name: Test LXD Image
        working-directory: ./tests
        run: |
          lxc exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' &
          python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
            echo "Activation test failed!"
            echo "Geckodriver logs:"
            tail -n 20 geckodriver.log >&2 || true
            echo "================"
            echo "ncp.log: "
            lxc exec ncp -- "tail -n20 /var/log/ncp.log"
            exit 1
          }
          python system_tests.py --non-interactive || {
            echo "System test failed!"
            exit 1
          }
          python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
            echo "Nextcloud test failed!"
            echo "Geckodriver logs:"
            tail -n 20 geckodriver.log >&2 || true
            echo "================"
            echo "ncp.log: "
            lxc exec ncp -- "tail -n20 /var/log/ncp.log"
            exit 1
          }
          lxc stop ncp

  test-update:
    needs:
      - update-previous
    runs-on: ubuntu-20.04
    env:
      VERSION: "${{ inputs.git_ref || github.head_ref || github.ref_name }}"
      ARTIFACT_NAME: ${{ needs.update-previous.outputs.artifact_name }}
      ARTIFACT_FILE: ${{ needs.update-previous.outputs.artifact_file }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: "${{ env.VERSION }}"
      - uses: whywaita/setup-lxd@v1
        with:
          lxd_version: latest/stable
      - name: Fix LXD
        run: |
          lxc profile create network
          cat <<EOF | lxc profile edit network
          devices:
            eth0:
              name: eth0
              network: lxdbr0
              type: nic
          EOF
      - name: Setup Firefox
        uses: browser-actions/setup-firefox@latest
      - name: Setup GeckoDriver
        uses: ChlodAlejandro/setup-geckodriver@latest
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Selenium
        run: pip install selenium
      - name: download LXD image from artifact store
        uses: actions/download-artifact@v3
        with:
          name: ${{ env.ARTIFACT_NAME }}
      - name: Launch ncp container
        run: |
          set -x
          lxc delete -q -f ncp || true
          lxc image import -q "./${ARTIFACT_FILE?}" --alias "ncp/test"
          systemd-run --user --scope -p "Delegate=yes" lxc launch -q "ncp/test" ncp
          lxc exec ncp -- bash -c 'while [ "$(systemctl is-system-running 2>/dev/null)" != "running" ] && [ "$(systemctl is-system-running 2>/dev/null)" != "degraded" ]; do :; done'
          sleep 30
          ip="$(lxc list -c n4 -f csv | grep '^ncp' | cut -d ',' -f2)"
          ip="${ip/% *}"
          echo "${ip} nextcloudpi.local" | sudo tee /etc/hosts
      - name: Test LXD Image
        working-directory: ./tests
        run: |
          lxc exec ncp -- bash -c 'tail -f /var/log/ncp.log' |& awk '{ print "NCP::" $0 }' &
          python activation_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
            echo "Activation test failed!"
            echo "Geckodriver logs:"
            tail -n 20 geckodriver.log >&2 || true
            echo "================"
            echo "ncp.log: "
            lxc exec ncp -- "tail -n20 /var/log/ncp.log"
            exit 1
          }
          python system_tests.py --non-interactive || {
            echo "System test failed!"
            exit 1
          }
          python nextcloud_tests.py --no-gui "nextcloudpi.local" 443 4443 || {
            echo "Nextcloud test failed!"
            echo "Geckodriver logs:"
            tail -n 20 geckodriver.log >&2 || true
            echo "================"
            echo "ncp.log: "
            lxc exec ncp -- "tail -n20 /var/log/ncp.log"
            exit 1
          }
          lxc stop ncp
