---
version: "3"
set: [errexit, pipefail, nounset]
shopt: [globstar]
env:
  GENERATION_IN_DAYS: 20d

tasks:
  check:sh:
    desc: Check SH files, will call all check:sh:* tasks
    cmds:
      - task: check:sh:shellcheck
      - task: check:sh:shfmt
  check:sh:shellcheck:
    desc: Pass Shellcheck on all *.sh files
    cmds:
      - find . -type f -name "*.sh" -exec shellcheck {} \;
    sources:
      - "**/*.sh"
  check:sh:shfmt:
    desc: Pass shfmt in check mode on all sh files
    cmds:
      - find . -type f -name "*.sh" -exec shfmt -d -ln bash -i 4 {} \;
    sources:
      - "**/*.sh"
  check:typos:
    desc: Check typos in all files
    cmds:
      - typos .
  check:flake:
    desc: Check flake
    cmds:
      - nix flake check
    sources:
      - "**/*.nix"

  host:*:update:
    desc: Update package version then build NixOS and Home-Manager
    vars:
      TARGET: "{{index .MATCH 0}}"
    cmds:
      - nix flake update
      - task: nixos:build:{{.TARGET}}
      - task: home:build:{{.TARGET}}
    preconditions:
      - sh: '[[ -d ./hosts/{{.TARGET}} ]]'
        msg: host `{{.TARGET}}` not found in `hosts/` directory

  host:*:switch:
    desc: Switch both Home-Manager and NixOS generations
    vars:
      TARGET: "{{index .MATCH 0}}"
    cmds:
      - task: nixos:switch:{{.TARGET}}
      - task: home:switch:{{.TARGET}}
    preconditions:
      - sh: '[[ -d ./hosts/{{.TARGET}} ]]'
        msg: host `{{.TARGET}}` not found in `hosts/` directory

  nixos:*:*:
    desc: Manage NixOS build, use nixos:verb:target format
    vars:
      VERB: "{{index .MATCH 0}}"
      TARGET: "{{index .MATCH 1}}"
    preconditions:
      - sh: '[[ {{.VERB}} = build || {{.VERB}} = test || {{.VERB}} = switch ]]'
        msg: verb must be build, test or switch
    cmds:
      - task: nixos:{{.VERB}}
        vars:
          TARGET: "{{.TARGET}}"

  nixos:build:
    internal: true
    cmds:
      - nixos-rebuild --flake .#{{.TARGET}} build
    requires:
      vars: [TARGET]
  
  nixos:switch:
    internal: true
    cmds:
      - doas nixos-rebuild --flake .#{{.TARGET}} switch
    requires:
      vars: [TARGET]

  nixos:test:
    internal: true
    cmds:
      - doas nixos-rebuild --flake .#{{.TARGET}} test
    requires:
      vars: [TARGET]

  nixos:list-gen:
    desc: List Nixos generations
    cmds:
      - nixos-rebuild list-generations

  nixos:gc:
    desc: Garbage collect NixOS
    cmds:
      - doas nix-collect-garbage --delete-older-than {{.GENERATION_IN_DAYS}}

  home:*:*:
    desc: Manage Home-Manager configuration, use home:verb:target format
    vars:
      VERB: "{{index .MATCH 0}}"
      TARGET: "{{index .MATCH 1}}"
    preconditions:
      - sh: '[[ {{.VERB}} = build || {{.VERB}} = switch ]]'
        msg: verb must be build or switch
    cmds:
      - task: home:{{.VERB}}
        vars:
          TARGET: "{{.TARGET}}"

  home:build:
    internal: true
    cmds:
      - home-manager build --flake .#{{.TARGET}}
    requires:
      vars: [TARGET]

  home:switch:
    internal: true
    cmds:
      - home-manager switch --flake .#{{.TARGET}}
    requires:
      vars: [TARGET]

  home:list-gen:
    desc: List Home-Manager generations
    cmds:
      - home-manager generations

  home:gc:
    desc: Garbage collect Home-Manager packages
    cmds:
      - home-manager expire-generations {{.GENERATION_IN_DAYS}}
      - nix store gc
