# 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’).
{
  lib,
  config,
  pkgs,
  ...
}: let
  wekan-compose = pkgs.fetchurl {
    url = "https://github.com/wekan/wekan/raw/v6.68/docker-compose.yml";
    sha256 = "sha256-gLZ8bZZ8ZMo1NGz3ooIgXRH6JuMoEMp+to7lfqAvc6E=";
  };
  # wekan-private = pkgs.runCommand "wekan-private" {} ''
  #   cp ${wekan-compose} $out
  #   sed -i '/localtime/d' $out
  #   sed -i '/timezone/d' $out
  #   sed -i 's/80:8080/7897:8080/g' $out
  #   sed -i 's/ROOT_URL=.*/ROOT_URL=https:\/\/reflector\.beam\/kanban\//' $out
  # '';
  wekan-rhizome = pkgs.runCommand "wekan-rhizome" {} ''
    cp ${wekan-compose} $out
    sed -i '/localtime/d' $out
    sed -i '/timezone/d' $out
    sed -i 's/80:8080/7897:8080/g' $out
    sed -i 's/ROOT_URL=.*/ROOT_URL=https:\/\/board\.rhizome\.tf\//' $out
  '';
  foswiki-compose = pkgs.fetchurl {
    url = "https://raw.githubusercontent.com/timlegge/docker-foswiki/master/docker-compose.1-simple.yml";
    sha256 = "sha256-XqGWGTZ/URKsIdDEEpBQUK7xoIdZ164lRhHEiWdnKpM=";
  };
in {
  imports = [
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
    # ./cachix.nix
    # (import (builtins.fetchTarball "https://github.com/jonascarpay/declarative-cachix/archive/master.tar.gz"))
  ];

  # cachix = [
  #   "nix-community"
  # ];

  nix.settings.experimental-features = ["flakes" "nix-command"];
  # systemd.services.NetworkManager-wait-online.enable = false;

  # Use the GRUB 2 boot loader.
  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  boot.loader.grub.device = "/dev/vda"; # or "nodev" for efi only

  networking.hostName = "reflector"; # Define your hostname.
  networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.

  # Set your time zone.
  time.timeZone = "Australia/Sydney";

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.sunshine = {
    isNormalUser = true;
    extraGroups = ["wheel"]; # Enable ‘sudo’ for the user.
    packages = with pkgs; [];
    openssh.authorizedKeys.keys = [
      "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDSQC8VgKLzoU5BSynJJuC8BFqAEN8JlSIzsZ2Vg9rfXHM7T4vbWtnxSCSbNw3CEnZCfrdDQTeRum7Uq+gvrcHWd9Aj+rVmubTdud70ybW7T7SlGv3b5TYBhMNbrAz0JIJjLnFMy3/pWids1v6mKW3i7k6Kbq8fSt7jva5Yg5x1jtkUUwvjSZjPg/E/Zl0hAcnx8fWe4foFTcYYsUbfEpp6bxdN2QuVmb17UKnLrMz6JTj88Jd2uYZkeKxGOwk+uwrd0WArY8JIiRi1NcPA3I42aAQfZKxCUY/xmVyRlF+l6K8caD4CZlysms9aXQzBhmPPDIY87AwyRlVK5JsRbaMEBMsffX2xk8DdV+2+9RbztgeXOoYk7WjJX1/+WcxY3RGn8QsUfrGALmrQTRGXgYRbtM/ZJq1m9aP6IvVQeKE1NOpKguXpmokB7JsyKPcWk/PCMVYyXM/qYspc6hRPJgGWiJsayj7myO6X5Ssl9uQnHpNNyrQNY+cx3/boBu2J1sM= bolt@quiver"
    ];
  };

  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    helix
    ripgrep
    fd
    curl

    cachix
    headscale

    comma

    woodpecker-agent
    woodpecker-server

    # podman
    # podman-compose
    # shadow

    dufs
  ];

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

  # services.resolved = {
  #   enable = true;
  #   fallbackDns = [ "103.1.206.179" "168.138.8.38" "168.138.12.137" ];
  #   dnssec = "false";
  # };

  services.fail2ban.enable = true;

  services.tailscale.enable = true;

  services.headscale = {
    enable = true;
    serverUrl = "https://net.atagen.co";
    dns = {
      nameservers = ["103.1.206.179" "168.138.8.38" "168.138.12.137"];
      magicDns = true;
    };
  };

  services.syncthing = {
    enable = true;
    extraOptions = {
      gui = {
        insecureSkipHostcheck = true;
      };
    };
  };

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

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

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

  users.users.dufs = {
    isSystemUser = true;
    createHome = true;
    group = "dufs";
  };
  users.groups.dufs = {};

  systemd.services.woodpecker-server = {
    wantedBy = ["multi-user.target"];
    description = "woodpecker CI/CD server";
    serviceConfig = {
      Environment = [
        "WOODPECKER_OPEN=true"
        "WOODPECKER_ADMIN=atagen"
        "WOODPECKER_REPO_OWNERS=rhizome"
        "WOODPECKER_HOST=https://ci.atagen.co"
        "WOODPECKER_GITEA=true"
        "WOODPECKER_GITEA_URL=https://git.atagen.co"
        "WOODPECKER_GITEA_CLIENT=1418f1d9-e2ce-4e8f-b8b2-7cf714baa07e"
        "WOODPECKER_GITEA_SECRET=gto_chpk65trvfbnrqs4cog62kn7sgmvpizg5wbr4zknb54o4gxlssba"
        "WOODPECKER_GITEA_SKIP_VERIFY=true"
        "WOODPECKER_AGENT_SECRET=71a0ac7d617aef46fb93811c6e2a300e041a324727df12b4805d5f4e9e1f3326"
        "WOODPECKER_DATABASE_DATASOURCE=/var/lib/woodpecker/woodpecker.sqlite"
      ];
      Restart = "always";
      ExecStart = "${pkgs.woodpecker-server}/bin/woodpecker-server";
      User = "ci";
      Group = "ci";
    };
  };

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

  # systemd.services.wekan-private = {
  #   wantedBy = [ "multi-user.target" ];
  #   after = [ "network.target" "docker.service" ];
  #   requires = [ "docker.service" ];
  #   description = "wekan kanban board";
  #   serviceConfig = {
  #     Restart = "always";
  #     User = "root";
  #     ExecStart = "${pkgs.docker}/bin/docker compose -f ${wekan-private} up";
  #     ExecStop = "${pkgs.docker}/bin/docker compose -f ${wekan-private} down";
  #   };
  # };

  systemd.services.wekan-rhizome = {
    wantedBy = ["multi-user.target"];
    after = ["network.target" "docker.service"];
    requires = ["docker.service"];
    description = "wekan kanban board for rhizomers";
    serviceConfig = {
      Restart = "always";
      User = "root";
      ExecStart = "${pkgs.docker}/bin/docker compose -f ${wekan-rhizome} up";
      ExecStop = "${pkgs.docker}/bin/docker compose -f ${wekan-rhizome} down";
    };
  };

  systemd.services.dufs = {
    wantedBy = ["multi-user.target"];
    after = ["network.target"];
    description = "dufs webdav server";
    serviceConfig = {
      User = "dufs";
      Restart = "always";
      ExecStart = "${pkgs.dufs}/bin/dufs -b 127.0.0.1 -p 8083 /home/dufs/files";
    };
  };

  # systemd.services.foswiki = {
  #   wantedBy = [ "multi-user.target" ];
  #   after = [ "network.target" "docker.service" ];
  #   requires = [ "docker.service" ];
  #   description = "foswiki wiki site";
  #   serviceConfig = {
  #     Restart = "always";
  #     User = "root";
  #     ExecStart = "${pkgs.docker}/bin/docker compose -f ${foswiki-compose} up";
  #     ExecStop = "${pkgs.docker}/bin/docker compose -f ${foswiki-compose} down";
  #   };
  # };

  services.caddy = {
    enable = true;
    virtualHosts = {
      "atagen.co" = {
        serverAliases = ["www.atagen.co"];
        extraConfig = ''
          respond "i live.. again"
        '';
      };

      "iced-rs.info".extraConfig = ''
        reverse_proxy http://127.0.0.1:8765
      '';

      "ci.atagen.co".extraConfig = ''
        reverse_proxy http://127.0.0.1:8000
      '';

      # "ci.rhizome.tf".extraConfig = ''
      #   reverse_proxy http://127.0.0.1:8000
      # '';

      "git.atagen.co".extraConfig = ''
        reverse_proxy http://127.0.0.1:3033
      '';

      # "git.rhizome.tf".extraConfig = ''
      #   reverse_proxy http://127.0.0.1:3033
      # '';

      "board.rhizome.tf".extraConfig = ''
        reverse_proxy http://127.0.0.1:7897
      '';

      "net.atagen.co".extraConfig = ''
        reverse_proxy http://127.0.0.1:8080
      '';

      "reflector.beam".extraConfig = ''
        tls /etc/selfsigned/cert.pem /etc/selfsigned/key.pem

        route /sync/* {
          uri strip_prefix /sync
          reverse_proxy http://127.0.0.1:8384
        }

        route /philez/* {
          uri strip_prefix /philez
          reverse_proxy http://127.0.0.1:8083
        }
      '';
    };
  };

  # Enable the OpenSSH daemon.
  services.openssh = {
    enable = true;
    passwordAuthentication = false;
    kbdInteractiveAuthentication = false;
    permitRootLogin = "no";
  };

  networking.firewall = {
    enable = true;
    trustedInterfaces = ["tailscale0"];
    checkReversePath = "loose";
    allowedTCPPorts = [80 443 6660];
    allowedUDPPorts = [80 443 41641 6660];
  };

  # Copy the NixOS configuration file and link it from the resulting system
  # (/run/current-system/configuration.nix). This is useful in case you
  # accidentally delete configuration.nix.
  system.copySystemConfiguration = true;

  # 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 = "22.11"; # Did you read the comment?
}
