{
  lib,
  pkgs,
  configVars,
  inputs,
  config,
  ...
}: let
  pubKeys = lib.filesystem.listFilesRecursive ../../users/keys;
  containerName = "bd-worker";
  containerIp = configVars.networking.addresses.bd-worker.ip;
  gatewayIp = configVars.networking.addresses.gateway.ip;
  postgresIp = configVars.networking.addresses.postgres.ip;
  postgresPort = toString configVars.networking.addresses.postgres.port;
  bitcoindIp = configVars.networking.addresses.bitcoin-node.ip;
  bitcoindPort = toString configVars.networking.addresses.bitcoin-node.services.bitcoind.port;

  #secrets
  sshKeyFile = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."ssh_keys/baseddata-models-access/id_ed25519".path;
  notifybotUsername = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."comms/xmpp/notifybot/username".path;
  notifybotPwd = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."comms/xmpp/notifybot/password".path;
  recipientUsername = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."comms/xmpp/mrsu/username".path;
  postgresUser = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/baseddata/user_username".path;
  postgresPassword = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/postgres/baseddata/user_password".path;
  bitcoindRPCUsername = lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/bitcoind/username".path;
  bitcoindRPCPassword= lib.optionalString (lib.hasAttr "sops-nix" inputs) config.sops.secrets."software/bitcoind/bitcoin-rpcpassword-public".path;
  baseddataEnv = "dev";
in {
  sops.secrets = {
    "ssh_keys/baseddata-models-access/id_ed25519" = {};
    "comms/xmpp/notifybot/username" = {};
    "comms/xmpp/notifybot/password" = {};
    "comms/xmpp/mrsu/username" = {};
    "software/postgres/baseddata/user_password" = {};
    "software/postgres/baseddata/user_username" = {};
    "software/bitcoind/username" = {};
    "software/bitcoind/bitcoin-rpcpassword-public" = {};
  };
  environment.persistence."/persist" = {
    hideMounts = true;
    directories = [
      "/var/lib/nixos-containers/${containerName}"
    ];
  };

  imports = [
    ../dbt_profiles.nix
  ];

  networking.nat.enable = true;
  networking.nat.internalInterfaces = ["ve-+"];
  networking.nat.externalInterface = "br0";

  containers.${containerName} = {
    autoStart = true;
    privateNetwork = true;
    hostBridge = "br0";
    nixpkgs = pkgs.path;
    bindMounts = {
      "/root/.ssh/id_ed25519" = {
        hostPath = "${sshKeyFile}";
        isReadOnly = true;
      };
      "/run/secrets/notifybotUsername" = {
        hostPath = "${notifybotUsername}";
        isReadOnly = true;
      };
      "/run/secrets/notifybotPassword" = {
        hostPath = "${notifybotPwd}";
        isReadOnly = true;
      };
      "/run/secrets/recipientUsername" = {
        hostPath = "${recipientUsername}";
        isReadOnly = true;
      };
      "/run/secrets/postgresPassword" = {
        hostPath = "${postgresPassword}";
        isReadOnly = true;
      };
      "/run/secrets/postgresUser" = {
        hostPath = "${postgresUser}";
        isReadOnly = true;
      };
      "/run/secrets/bitcoindRPCPassword" = {
        hostPath = "${bitcoindRPCPassword}";
        isReadOnly = true;
      };
      "/run/secrets/bitcoindRPCUsername" = {
        hostPath = "${bitcoindRPCUsername}";
        isReadOnly = true;
      };
      "/media/baseddata-data" = {
        hostPath = "/media/main-ssd/baseddata-data";
        isReadOnly = false;
      };
      "/root/.dbt/profiles.yml" = {
        hostPath = "/run/secrets/templates/dbt/profiles.yml";
        isReadOnly = false;
      };
    };

    config = {
      pkgs,
      lib,
      ...
    }: {
      networking = {
        defaultGateway = "${gatewayIp}";
        interfaces.eth0.ipv4.addresses = [
          {
            "address" = "${containerIp}";
            "prefixLength" = 24;
          }
        ];
        firewall = {
          enable = true;
          allowedTCPPorts = [
            4200
          ];
        };
        useHostResolvConf = lib.mkForce false;
      };

      services.resolved.enable = true;

      environment.systemPackages = [
        pkgs.vim
        pkgs.git
        pkgs.python311
        pkgs.poetry
        pkgs.aria2
        pkgs.osmctools
        pkgs.osmium-tool
        pkgs.osm2pgsql
      ];

      environment.variables = {
        BASEDDATA_ENVIRONMENT = "dev";
        NIX_LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
        NIX_LD = "/run/current-system/sw/share/nix-ld/lib/ld.so";
        LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
      };

      systemd.services.baseddata-deploy-service = {
        wantedBy = ["multi-user.target"];
        after = ["network.target"];
        description = "Initiates deployment of application and builds python environment using Poetry";
        environment = {
          BASEDDATA_ENVIRONMENT = "${baseddataEnv}";
        };
        serviceConfig = {
          ExecStart = pkgs.writeShellScript "baseddata-deploy-service" ''
            GITCMD="${pkgs.openssh}/bin/ssh -i /root/.ssh/id_ed25519"
            if [ ! -d "/srv/baseddata-models" ]; then
              GIT_SSH_COMMAND=$GITCMD  ${pkgs.git}/bin/git clone --branch $BASEDDATA_ENVIRONMENT git@git.bitlab21.com:sam/baseddata-models.git /srv/baseddata-models
            else
              cd /srv/baseddata-models
              GIT_SSH_COMMAND=$GITCMD ${pkgs.git}/bin/git stash --include-untracked
              GIT_SSH_COMMAND=$GITCMD ${pkgs.git}/bin/git pull
            fi

            cd /srv/baseddata-models
            mkdir .venv
            ${pkgs.poetry}/bin/poetry lock --no-update
            ${pkgs.poetry}/bin/poetry install
          '';
          Restart = "on-failure";
        };
      };

      systemd.services.baseddata-prefect-server = {
        wantedBy = ["multi-user.target"];
        after = ["baseddata-deploy-service.target"];
        description = "Initates the Prefect server";
        environment = {
          NIX_LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
          NIX_LD = "/run/current-system/sw/share/nix-ld/lib/ld.so";
          LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
          PREFECT_API_URL = "http://${containerIp}:4200/api";
          BASEDDATA_ENVIRONMENT = "${baseddataEnv}";
        };
        serviceConfig = {
          WorkingDirectory = "/srv/baseddata-models";
          ExecStart = pkgs.writeShellScript "baseddata-prefect-server" ''

            # run prefect server
            .venv/bin/prefect server start --host 0.0.0.0

          '';
          Restart = "on-failure";
        };
      };

      systemd.services.baseddata-serve-flows = {
        wantedBy = ["multi-user.target"];
        after = ["baseddata-prefect-server.target"];
        description = "Serves the Prefect flows";
        path = ["/run/current-system/sw" "/srv/baseddata-models/.venv"];
        environment = {
          PREFECT_API_URL = "http://${containerIp}:4200/api";
          BASEDDATA_ENVIRONMENT = "${baseddataEnv}";
          NIX_LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
          NIX_LD = "/run/current-system/sw/share/nix-ld/lib/ld.so";
          LD_LIBRARY_PATH = "/run/current-system/sw/share/nix-ld/lib";
        };
        serviceConfig = {
          WorkingDirectory = "/srv/baseddata-models";
          ExecStartPre = "${pkgs.coreutils}/bin/timeout 120 ${pkgs.bash}/bin/bash -c 'until ${pkgs.netcat-openbsd}/bin/nc -z ${containerIp} 4200; do sleep 3; done'";
          ExecStart = pkgs.writeShellScript "baseddata-serve-flows" ''

            # set prefect environment variables
            .venv/bin/prefect variable set "xmpp_jid" $(cat /run/secrets/notifybotUsername) --overwrite
            .venv/bin/prefect variable set "xmpp_password" $(cat /run/secrets/notifybotPassword) --overwrite
            .venv/bin/prefect variable set "xmpp_recipient" $(cat /run/secrets/recipientUsername) --overwrite

            .venv/bin/prefect variable set "postgres_host" ${postgresIp} --overwrite
            .venv/bin/prefect variable set "postgres_port" ${postgresPort} --overwrite
            .venv/bin/prefect variable set "postgres_user" $(cat /run/secrets/postgresUser) --overwrite
            .venv/bin/prefect variable set "postgres_pwd" $(cat /run/secrets/postgresPassword) --overwrite
            .venv/bin/prefect variable set "postgres_dbname" "baseddata" --overwrite
            .venv/bin/prefect variable set "postgres_schema" "models_final" --overwrite

            .venv/bin/prefect variable set "bitcoin_rpc_password" $(cat /run/secrets/bitcoindRPCPassword) --overwrite
            .venv/bin/prefect variable set "bitcoin_rpc_username" $(cat /run/secrets/bitcoindRPCUsername) --overwrite
            .venv/bin/prefect variable set "bitcoind_ip" ${bitcoindIp} --overwrite
            .venv/bin/prefect variable set "bitcoind_port" ${bitcoindPort} --overwrite

            .venv/bin/prefect variable set "osm_dir" "/media/baseddata-data/osm" --overwrite
            .venv/bin/prefect variable set "wdpa_dir" "/media/baseddata-data/wdpa" --overwrite

            .venv/bin/prefect variable set "dbt_profiles_dir" "/root/.dbt" --overwrite


            # serve flows
            .venv/bin/python automation/flows/serve-flows.py
          '';
          Restart = "on-failure";
        };
      };

      programs.nix-ld.enable = true;
      programs.nix-ld.libraries = with pkgs; [
        zlib
        libgcc
      ];

      programs.ssh.knownHosts = {
        "git.bitlab21.com" = {
          publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIALNd2BGf64heYjWT9yt0fVmngepiHRIMsL7au/MRteg";
        };
      };

      services.openssh = {
        enable = true;
        settings.PasswordAuthentication = false;
      };

      users.users.root = {
        openssh.authorizedKeys.keys = lib.lists.forEach pubKeys (key: builtins.readFile key);
      };

      system.stateVersion = "24.05";
    };
  };
}