name: ci

on:
  pull_request:
  push:
    branches:
      - "main"
  schedule:
    - cron: "6 */12 * * *"

jobs:
  # there is some undesirable behavior when running tests because nektos/act mimicks github actions.
  # we are banned from github so we aren't using that. instead, we use gitea act_runner.
  # github actions Job runner runs on docker 'host' network.
  # gitea act_runner runs on a custom named bridge network. e.g. `GITEA-ACTIONS-TASK-974_WORKFLOW-ci_JOB-Tests-Checks-test_phoenix-network`
  # confusing, right? It totally is!
  # when we are working with gitea act_runner, we can use dns names, e.g. test-db.
  # when we are working with nektos/act, we must use the IP address of the service container.
  # this causes issues because nektos/act will not be able to find test-db:5432 but act_runner can.
  # this means we have inconsistent behavior across testing environments, which is bad.
  # our workaround is to reference service containers two different ways.
  #   - when running nektos/act on localhost, we reference the service as localhost:<port_number>.
  #   - when running gitea act_runner on gitea, we reference the service's dns name.
  # these references are defined in environment variables
  test_phoenix:
    env:
      SECRET_KEY_BASE: ${{ secrets.SECRET_KEY_BASE }}
      MIX_ENV: test
      TRACKER_URL: ${{ vars.TRACKER_URL }}
      AWS_BUCKET: ${{ vars.AWS_BUCKET }}
      AWS_HOST: ${{ vars.AWS_HOST }}
      AWS_REGION: ${{ vars.AWS_REGION }}
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      PUBLIC_S3_ENDPOINT: ${{ vars.PUBLIC_S3_ENDPOINT }}
      SITE_URL: https://futureporn.net
      TRACKER_HELPER_URL: ${{ vars.TRACKER_HELPER_URL }}
      TRACKER_HELPER_USERNAME: ${{ secrets.TRACKER_HELPER_USERNAME }}
      TRACKER_HELPER_PASSWORD: ${{ secrets.TRACKER_HELPER_PASSWORD }}
      TRACKER_HELPER_ACCESSLIST_URL: ${{ vars.TRACKER_HELPER_ACCESSLIST_URL }}
      TRACKER_HELPER_ACCESSLIST_PATH: /var/lib/aquatic/accesslist

      DB_NAME: ${{ vars.DB_NAME }}
      DB_HOST: ${{ vars.DB_HOST }}
      DB_PORT: ${{ vars.DB_PORT }}
      DB_USER: ${{ vars.DB_USER }}
      DB_PASS: ${{ secrets.DB_PASS }}
    name: Tests & Checks
    runs-on: ubuntu-22.04
    # container:
    #   image: catthehacker/ubuntu:act-22.04
    #   volumes:
    #     - aquatic:/var/lib/aquatic
    #     - /tmp/aquatic:/tmp/aquatic
    #     - /tmp/test:/root/test
    #     - /test2:/root/test2
    timeout-minutes: 20
    permissions:
      contents: read
      pull-requests: write

    services:
      test-db:
        image: postgres:16
        env:
          POSTGRES_DB: ${{ vars.DB_NAME }}
          POSTGRES_USER: ${{ vars.DB_USER }}
          POSTGRES_PASSWORD: ${{ secrets.DB_PASS }}
          PGUSER: ${{ vars.DB_USER }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      tracker:
        image: gitea.futureporn.net/futureporn/tracker:latest
        ports:
          - 5063:5063
          - 3003:3003
          - 9000:9000
        env:
          TRACKER_HELPER_ACCESSLIST_PATH: /var/lib/aquatic/accesslist
          TRACKER_HELPER_ACCESSLIST_URL: http://localhost:5063/accesslist
          TRACKER_HELPER_USERNAME: ${{ secrets.TRACKER_HELPER_USERNAME }}
          TRACKER_HELPER_PASSWORD: ${{ secrets.TRACKER_HELPER_PASSWORD }}
          TRACKER_HELPER_PORT: 5063
          ACCESS_LIST_CONTENTS: ""
          CONFIG_FILE_CONTENTS: |
            log_level = 'debug'
            [network]
            use_ipv4 = true
            use_ipv6 = true
            address_ipv4 = "0.0.0.0:3003"
            address_ipv6 = "[::]:3003"
            [statistics]
            interval = 5
            print_to_stdout = false
            run_prometheus_endpoint = true
            prometheus_endpoint_address = "0.0.0.0:9000"
            [access_list]
            mode = "allow"
            path = "/var/lib/aquatic/accesslist"
            [privileges]
            # Chroot and switch group and user after binding to sockets
            drop_privileges = true
            # Chroot to this path
            chroot_path = "/var/lib/aquatic"
            # Group to switch to after chrooting
            group = "nogroup"
            # User to switch to after chrooting
            user = "nobody"

    steps:
      # I wasn't successful with this. Something about the docker network in which the container runs?
      # - name: postgres service check
      #   env:
      #     PGPASSWORD: ${{ secrets.DB_PASS }}
      #   uses: docker://postgres:16
      #   with:
      #     args: /usr/bin/pg_isready --host test-db --port 5432

      - name: show the env
        run: |
          env | sort

      # - name: show the JOB_CONTAINER_ID
      #   run:
      #     options: --volumes-from ${{ env.JOB_CONTAINER_NAME }}

      - name: Setup FFmpeg
        uses: FedericoCarboni/setup-ffmpeg@v3

      - name: Setup futureporn cache dir
        run: |
          mkdir -p ~/.cache/futureporn

      - name: Setup PIP packages
        uses: insightsengineering/pip-action@v2
        with:
          packages: |
            torrentfile

      - name: Checkout code
        uses: actions/checkout@v4
        with:
          submodules: false

      - name: Setup Erlang and Elixir
        uses: erlef/setup-beam@v1.17
        with:
          elixir-version: "1.16.0-otp-26"
          otp-version: "26.0"

      # - name: Mix and build cache
      #   uses: actions/cache@v4
      #   with:
      #     path: |
      #       deps
      #       _build
      #     key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
      #     restore-keys: ${{ runner.os }}-mix-

      - name: Get dependencies
        run: mix deps.get
        working-directory: ./apps/bright

      - name: Code analyzers
        run: |
          mix format --check-formatted
          mix compile --warnings-as-errors
        working-directory: ./apps/bright

      - name: Unit tests
        run: |
          mix test --only=unit
        working-directory: ./apps/bright

      - name: Integration tests
        run: |
          mix test --only=integration
        working-directory: ./apps/bright

      - name: Acceptance tests
        run: |
          mix test --only=acceptance
        working-directory: ./apps/bright

      - name: Uncategorized tests (ideally there should be none)
        run: |
          mix test --exclude=acceptance --exclude=unit --exclude=integration
        working-directory: ./apps/bright

      - name: Code coverage
        run: |
          mix coveralls
        working-directory: ./apps/bright

      - name: Check for banned HTML elements (i.e. <a>)
        run: |
          if grep -R '</a>' ./lib; then
            echo "Found banned element '<a>' inside ./lib. Please use <.link> instead."
            exit 1
          fi
        working-directory: ./apps/bright