# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running `nixos-help`).
{
  pkgs,
  lib,
  ...
}:
{
  imports = [
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
  ];

  nix.settings.experimental-features = [
    "nix-command"
    "flakes"
  ];
  nix.extraOptions = ''
    keep-outputs = true
    keep-derivations = true
  '';

  environment.pathsToLink = [ "/share/zsh" ];
  programs.zsh.enable = true;
  users.defaultUserShell = pkgs.zsh;

  users.users.felix = {
    isSystemUser = true;
    group = "www";
    extraGroups = [ "docker" ];
  };

  users.users.spore = {
    isSystemUser = true;
    home = "/home/spore";
    createHome = true;
    useDefaultShell = true;
    group = "www";
    extraGroups = [ "docker" ];
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL9VRcCnmjCyV7DpCm8ir3+xPTbyMDBJhgSkhpmdFL5d spore@server.rhizome.tf"
    ];
  };

  users.groups.www = {
    members = [
      "acme"
      "felix"
      "spore"
    ];
  };

  boot.loader.grub.enable = true;
  boot.loader.grub.device = "/dev/vda"; # or "nodev" for efi only

  networking.hostName = "filament"; # Define your hostname.
  time.timeZone = "Australia/Sydney";

  i18n.defaultLocale = "en_AU.UTF-8";

  users.users.rhizome = {
    isNormalUser = true;
    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
    openssh.authorizedKeys.keys = [
      "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDSQC8VgKLzoU5BSynJJuC8BFqAEN8JlSIzsZ2Vg9rfXHM7T4vbWtnxSCSbNw3CEnZCfrdDQTeRum7Uq+gvrcHWd9Aj+rVmubTdud70ybW7T7SlGv3b5TYBhMNbrAz0JIJjLnFMy3/pWids1v6mKW3i7k6Kbq8fSt7jva5Yg5x1jtkUUwvjSZjPg/E/Zl0hAcnx8fWe4foFTcYYsUbfEpp6bxdN2QuVmb17UKnLrMz6JTj88Jd2uYZkeKxGOwk+uwrd0WArY8JIiRi1NcPA3I42aAQfZKxCUY/xmVyRlF+l6K8caD4CZlysms9aXQzBhmPPDIY87AwyRlVK5JsRbaMEBMsffX2xk8DdV+2+9RbztgeXOoYk7WjJX1/+WcxY3RGn8QsUfrGALmrQTRGXgYRbtM/ZJq1m9aP6IvVQeKE1NOpKguXpmokB7JsyKPcWk/PCMVYyXM/qYspc6hRPJgGWiJsayj7myO6X5Ssl9uQnHpNNyrQNY+cx3/boBu2J1sM= bolt@quiver"
      "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDW/YjnlHiEf2bV0RapVl+jWEtsNYrbXsaJJhXUkAaf61rsTZ2jpda7FmOVGjyJiOkTNYANoT83YhGxvKt3Ukcx5xG0JhcrilEGKfOR43/QLlXetCh4aFed//CXYNQo8obDovx9A8YamzfZWJo0nhshEAt1aDvNGlyPgHZI3r5vYNB6OpMlaSnr873i5hp6S9dxURoF0FjpdZwTWk5DiYUoZCezs6TfG6PzHbSsB88o4AUNZ6O+h1KD0lITSXH/v/M1zG8fkUzfZHFQoZ6VaIMhIVwLmbybvyb630IIfhx6KUoCWzCRlKBjVOGsQ1xZWEnjPgHB6atX5eNc/L8/bdyZOJ4aE2wSdVNMyriYuiyc3t/RwSvcRpfmzaxWUImDpjH3mxCrDymrZIQQTrNuC6o5O3mz3NCZRcFUZmuZXeYphyrzuNgAfsvHKMd8Fu+PdddSPCHkgYEIRuGD4flaujM8eUHZYqKkpmmiMwKk6jupBscN+1uwBqGQbaR0InXR+4c= custard"
    ];
  };

  users.users.ci = {
    isSystemUser = true;
    createHome = true;
    group = "ci";
    extraGroups = [ "docker" ];
  };

  users.users.ci-agent = {
    isSystemUser = true;
    createHome = true;
    group = "ci";
    extraGroups = [ "docker" ];
  };

  users.groups.ci = { };

  virtualisation = {
    docker.enable = true;
    # podman = {
    #   enable = true;
    #   dockerCompat = true;
    #   defaultNetwork.settings.dns_enabled = true;
    # };
  };

  services.fail2ban.enable = true;

  services.redis.servers."".enable = true;

  services.gitea = {
    enable = true;
    appName = "rhizome gitea";
    domain = "git.rhizome.tf";
    httpPort = 3036;
    settings.server = {
      START_SSH_SERVER = true;
      SSH_PORT = 6660;
      SSH_DOMAIN = "git.rhizome.tf";
      DISABLE_SSH = false;
    };
    rootUrl = "https://git.rhizome.tf";
    settings.service.DISABLE_REGISTRATION = true;
    settings.webhook.ALLOWED_HOST_LIST = "external,loopback";
  };

  # systemd.services.spore = {
  #   wantedBy = [ "multi-user.target" ];
  #   description = "Spore Deployment Tool";
  #   serviceConfig = {
  #     User = "spore";
  #     Restart = "on-failure";
  #     ExecStart = "${lib.getExe pkgs.spore}";

  #   };
  # };

  systemd.services.grab-keys = {
    description = "Server Key Grabber";
    serviceConfig = {
      Type = "oneshot";
      User = "spore";
      Restart = "on-failure";
      ExecStart = "${pkgs.openssh}/bin/scp spore@server.rhizome.tf:/etc/letsencrypt/live/server.rhizome.tf/cert.pem /var/www/server.pem";
    };
  };

  systemd.timers.grab-keys = {
    description = "Server Key Grabber";
    timerConfig = {
      Persistent = "yes";
      OnCalendar = "daily";
      Unit = "grab-keys.service";
    };
  };

  systemd.services.woodpecker-server = {
    wantedBy = [ "multi-user.target" ];
    description = "woodpecker CI/CD server";
    serviceConfig = {
      Environment = [
        "WOODPECKER_OPEN=true"
        "WOODPECKER_ADMIN=dbx"
        "WOODPECKER_REPO_OWNERS=rhizome"
        "WOODPECKER_HOST=https://ci.rhizome.tf"
        "WOODPECKER_GITEA=true"
        "WOODPECKER_GITEA_URL=https://git.rhizome.tf"
        "WOODPECKER_GITEA_CLIENT=86bb265b-8914-4abd-a3eb-f843fabbd79d"
        "WOODPECKER_GITEA_SECRET=gto_474i24aku3vda6wjbumdgfdcjdllclecfplfb4wsz2ibkemhdrwq"
        "WOODPECKER_GITEA_SKIP_VERIFY=true"
        "WOODPECKER_AGENT_SECRET=71a0ac7d617aef46fb93811c6e2a300e041a324727df12b4805d5f4e9e1f3326"
        "WOODPECKER_DATABASE_DATASOURCE=/var/lib/woodpecker/woodpecker.sqlite"
      ];
      Restart = "on-failure";
      ExecStart = "${lib.getExe pkgs.woodpecker-server}";
      User = "ci";
      Group = "ci";
    };
  };

  systemd.services.woodpecker-agent = {
    wantedBy = [ "multi-user.target" ];
    description = "woodpecker CI/CD agent";
    serviceConfig = {
      Environment = [
        "WOODPECKER_AGENT_SECRET=71a0ac7d617aef46fb93811c6e2a300e041a324727df12b4805d5f4e9e1f3326"
      ];
      Restart = "always";
      ExecStart = "${lib.getExe pkgs.woodpecker-agent}";
      User = "ci-agent";
      Group = "ci";
    };
  };

  systemd.services.felix = {
    wantedBy = [ "multi-user.target" ];
    description = "gilles on testing";
    serviceConfig = {
      ExecStart = ''${lib.getExe pkgs.docker} run --network host -v /var/lib/acme/rhizome.tf:/var/lib/acme/rhizome.tf --env-file /var/www/felix_env git.rhizome.tf/rhizome/gilles:latest'';
      Group = "www";
      User = "felix";
      Restart = "always";
    };
  };

  services.caddy = {
    enable = true;
    virtualHosts = {
      "rhizome.tf".extraConfig = ''
        route /.well-known/acme-challenge/* {
          root * /var/www/acme-challenge
          file_server
        }
        root * /var/www/rhizome.tf
        file_server
        handle_errors {
          @404 {
            expression {http.error.status_code} == 404
          }
          rewrite @404 /404.html
          file_server
        }
      '';
      "git.rhizome.tf".extraConfig = ''
        reverse_proxy http://localhost:3036
      '';
      "ci.rhizome.tf".extraConfig = ''
        reverse_proxy http://localhost:8000
      '';
    };
    group = "www";
  };

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    kitty
    helix
    ripgrep
    fd
    exa
    bat
    nix-index
    comma
    alejandra
    curl
    cachix
    git
    man-pages
    man-pages-posix
    rnix-lsp
    zellij
    zoxide
    fzf
    btop
  ];
  documentation.dev.enable = true;
  documentation.man.enable = true;
  documentation.enable = true;
  programs.nix-index-database.comma.enable = true;
  programs.nix-index.enableZshIntegration = false;
  programs.nix-index.enableBashIntegration = false;

  services.openssh = {
    enable = true;
    passwordAuthentication = false;
    kbdInteractiveAuthentication = false;
    permitRootLogin = "no";
  };

  networking.firewall.allowedTCPPorts = [
    22
    80
    443
    5539
    5559
    6660
  ];
  networking.firewall.allowedUDPPorts = [
    443
    6660
  ];

  security.acme = {
    acceptTerms = true;
    defaults.email = "admin@rhizome.tf";
    defaults.group = "www";
    certs."rhizome.tf" = {
      webroot = "/var/www/acme-challenge";
    };
  };

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It's perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "23.05"; # Did you read the comment?

  system.activationScripts = {
    acls.text = ''
      ${pkgs.acl}/bin/setfacl -Rm spore:rx /var/lib/acme/rhizome.tf
    '';
  };
}
