{ lib, config, pkgs, inputs, ... }:
let
 ClaytonXYZ = "/Block/ClaytonXYZ";
 nixpkgs-mautrix-nix = (import inputs.nixpkgs {
  system = "x86_64-linux";
  config = {
   permittedInsecurePackages = [ "olm-3.2.16" ];
  };
 });
in
{
 imports =
  [
   ./hardware-configuration.nix
   ./remoteBuild.nix
   ./grocy.nix
   ./tandoor.nix
   ./mealie.nix
   ./matomo.nix
   ./trilium.nix
  ];

 cos.grocy = {
   enable = true;
   dataDir = "/Block/grocy";
   hostname = "grocy.claytonhickey.me";
 };

 cos.tandoor = {
   enable = false;
   hostname = "tandoor.claytonhickey.me";
   port = 8123;
 };

 cos.mealie = {
   enable = false;
   port = 8129;
   hostname = "mealie.claytonhickey.me";
 };

 cos.matomo = {
   enable = false;
   hostname = "matomo.claytonhickey.me";
 };

 cos.trilium = {
   enable = true;
   hostname = "trilium.claytonhickey.me";
   dataDir = "/Block/trilium";
   port = 8578;
 };

 services.nginx.virtualHosts."claytonhickey.me_fs" =
 let
  mkWellKnown = data: ''
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
    return 200 '${builtins.toJSON data}';
   '';
 in
 {
  listen = [{
    addr = "127.0.0.1";
    port = 8302;
  }];
  locations."/" = {
   root = "/Block/claytonhickey_me/www";
  extraConfig = ''absolute_redirect off;'';
  };
  locations."= /.well-known/matrix/server".extraConfig = mkWellKnown {"m.server" = "matrix.claytonhickey.me:443";};
  locations."= /.well-known/matrix/client".extraConfig = mkWellKnown {"m.homeserver" = {base_url = "https://matrix.claytonhickey.me";};};
  locations."/.well-known/webfinger" = {
    extraConfig = ''
      add_header Access-Control-Allow-Origin '*';
    '';
    return = "301 https://mastodon.claytonhickey.me$request_uri";
  };
 };

 services.nginx.virtualHosts."matrix.claytonhickey.me" =
 {
  listen = [{
    addr = "127.0.0.1";
    port = 8303;
  }];
  locations."/".extraConfig = '' return 404; '';

  locations."/_matrix".proxyPass = "http://[::1]:8008";
  locations."/_synapse/client".proxyPass = "http://[::1]:8008";
 };

 services.nginx.virtualHosts."bikeability-rasterserver.claytonhickey.me" =
 {
  listen = [{
    addr = "127.0.0.1";
    port = 8304;
  }];
  locations."/".proxyPass = "http://10.100.0.2:9000/styles/bikeability/512/";
 };

 services.cloudflared = {
   enable = true;
   certificateFile = "/Block/cloudflare/cert.pem";
   tunnels = {
     "4fc85af1-38f7-4c96-856c-7c797c5e3bf8" = {
       credentialsFile = "/Block/cloudflare/4fc85af1-38f7-4c96-856c-7c797c5e3bf8.json";
       default = "http_status:404";
       ingress = {
         "languini.net" = "http://10.100.0.2:5267";
	 "claytondoesthings.xyz" = "http://127.0.0.1:5000";
	 "nextcloud.claytondoesthings.xyz" = "http://10.100.0.2:8120";
	 "bikeability.claytonhickey.me" = "http://10.100.0.2:8001";
	 "bikeability-tileserver.claytonhickey.me" = "http://10.100.0.2:8000";
	 "bikeability-rasterserver.claytonhickey.me" = "http://127.0.0.1:8304";
	 "claytonhickey.me" = "http://127.0.0.1:8302";
	 "jellyfin.claytonhickey.me" = "http://10.100.0.2:8096";
	 "forgejo.claytonhickey.me" = "unix://${config.services.forgejo.settings.server.HTTP_ADDR}";
	 "matrix.claytonhickey.me" = "http://127.0.0.1:8303";
	 "actual.claytonhickey.me" = "http://127.0.0.1:3000";
	 "mastodon.claytonhickey.me" = "http://10.100.0.2:5328";
       };
     };
   };
 };

 services.nginx.streamConfig = ''
   server {
     listen 25565 reuseport;
     proxy_pass 10.100.0.2:25565;
   }
   server {
     listen 25566 reuseport;
     proxy_pass 10.100.0.2:25566;
   }
 '';

 services.dnsmasq = {
   enable = true;
   settings = {
     address = [
       #"/nextcloud.claytondoesthings.xyz/fc10::1"
       #"/nextcloud.claytondoesthings.xyz/10.100.0.1"
       "/hydra.claytonhickey.me/10.100.0.2"
       #"/forgejo.claytonhickey.me/fc10::1"
       #"/forgejo.claytonhickey.me/10.100.0.1"
     ];
     #"dns-rr" = [
     #  "nextcloud.claytondoesthings.xyz,65,000100"
     #  "forgejo.claytonhickey.me,65,000100"
     #];
   };
 };

 boot.loader.grub.enable = true;
 networking = {
  hostName = "loadedskypotato"; # Define your hostname.
  networkmanager.enable = true;  # Easiest to use and most distros use this by default.
  usePredictableInterfaceNames = false;
  useDHCP = false;
  firewall = {
   allowedTCPPorts = [
    25565 # minecraft survival
    25566 # minecraft creative
   ];
   allowedUDPPorts = [
    51820 # wireguard
   ];
   interfaces.wg0 = {
     allowedUDPPorts = [
       53
     ];
     allowedTCPPorts = [
       53
     ];
   };
  };
  nat = {
   enable = true;
   enableIPv6 = true;
   externalInterface = "eth0";
   internalInterfaces = [
    "wg0"
   ];
  };
  wireguard = {
   enable = true;
   interfaces = {
    wg0 = {
     ips = [
       "10.100.0.1/32"
       "fc10::1/128"
     ];
     listenPort = 51820;
     #postSetup = ''
     # ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE
     # ${pkgs.iptables}/bin/iptables -t nat -A PREROUTING -i wg0 -p udp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/iptables -t nat -A PREROUTING -i wg0 -p tcp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fc10::2/128 -o eth0 -j MASQUERADE
     # ${pkgs.iptables}/bin/ip6tables -t nat -A PREROUTING -i wg0 -p udp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/ip6tables -t nat -A PREROUTING -i wg0 -p tcp --dport 53 -j REDIRECT --to-ports 53
     #'';
     #postShutdown = ''
     # ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.100.0.0/24 -o eth0 -j MASQUERADE
     # ${pkgs.iptables}/bin/iptables -t nat -D PREROUTING -i wg0 -p udp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/iptables -t nat -D PREROUTING -i wg0 -p tcp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fc10::2/128 -o eth0 -j MASQUERADE
     # ${pkgs.iptables}/bin/ip6tables -t nat -D PREROUTING -i wg0 -p udp --dport 53 -j REDIRECT --to-ports 53
     # ${pkgs.iptables}/bin/ip6tables -t nat -D PREROUTING -i wg0 -p tcp --dport 53 -j REDIRECT --to-ports 53
     #'';
     privateKeyFile = "/Block/wireguard-keys/private";
     peers = [
      { # fire-media-server
        publicKey = "TnuODb+I5wfF6z5wlwOFiRr4CKImY557OIXyZCXPSio=";
        # List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
        allowedIPs = [ "10.100.0.2/32" "fc10::2/128"];
      }
      { # laptop
        publicKey = "7Hi/p1DEnAejX5vf46ul1ZWAeGM9nuWWGXXr9f6sUWA=";
        allowedIPs = [ "10.100.0.3/32" "fc10::3/128"  ];
      }
      { # phone
        publicKey = "UAP8/k1zWInrksQQAf0NuDUD1b0K0djDVUcYl+DNMEE=";
        allowedIPs = [ "10.100.0.4/32" ];
      }
      { # desktop
        publicKey = "w054mlSBBq4u0ilTYfwc2xbb5Z+7kEigikSZ3R0u73w=";
        allowedIPs = [ "10.100.0.5/32" ];
      }
      { # octonix
        publicKey = "5l1fL2LJP5yhuLoqfEtlR5/DJ6h+F+iLEKlr/uaI02o=";
        allowedIPs = [ "10.100.0.6/32" ];
      }
     ];
    };
   };
  };
 };

 time.timeZone = "America/New_York";

 services = {
  openssh = {
   enable = true;
   settings.PermitRootLogin = "yes";
   settings.PasswordAuthentication = false;
  };
  forgejo = {
   enable = true;
   settings = {
    server = {
     PROTOCOL = "http+unix";
     ROOT_URL = "https://forgejo.claytonhickey.me/";
    };
    service.DISABLE_REGISTRATION = true;
   };
  };

  actual = {
   enable = true;
   settings = {
    hostname = "127.0.0.1";
   };
  };

  nginx = {
   enable = true;

   recommendedProxySettings = true;
   recommendedTlsSettings = true;

   clientMaxBodySize = "1G";
   
   logError = "/var/log/nginx/error.log";

   virtualHosts = {

    "default_server" = {
      default = true;
      rejectSSL = true;
      locations."/".return = 404;
    };
   };
  };
  postgresql = {
   enable = true;
   ensureDatabases = [
    "matrix-synapse"
    #"mautrix-gmessages"
    "mautrix-discord"
   ];
   ensureUsers = [
    {
     name = "matrix-synapse";
     ensureDBOwnership = true;
    }
    #{
    # name = "mautrix-gmessages";
    # ensureDBOwnership = true;
    # ensureClauses = {
    #  login = true;
    # };
    #}
    {
     name = "mautrix-discord";
     ensureDBOwnership = true;
     ensureClauses = {
      login = true;
     };
    }
   ];
   authentication = pkgs.lib.mkOverride 10 ''
     #type database  DBuser  auth-method
     local all       all     trust
     host  sameuser    all     127.0.0.1/32 scram-sha-256
     host  sameuser    all     ::1/128 scram-sha-256
    '';
  };
  matrix-synapse = {
   enable = true;
   settings = {
    server_name = "claytonhickey.me";
    public_baseurl = "https://matrix.claytonhickey.me";
    listeners = [
     {
      port = 8008;
      bind_addresses = [ "::1" ];
      type = "http";
      tls = false;
      x_forwarded = true;
      resources = [
       {
        names = [ "client" "federation" ];
        compress = true;
       }
      ];
     }
    ];
    app_service_config_files = [
     #"/var/lib/matrix-synapse/slack-registration.yaml"
     #"/var/lib/matrix-synapse/gmessages-registration.yaml"
     "/var/lib/matrix-synapse/discord-registration.yaml"
    ];
   };
  };
  mautrix-meta = {
   instances = {
    instagram = {
     enable = true;
     registerToSynapse = true;
     settings = {
      network = {
       mode = "instagram";
       ig_e2ee = true;
       displayname_template = "{{or .DisplayName .Username \"Unknown User\"}}";
       proxy_media = false;
       min_full_reconnect_interval_seconds = 3600;
       force_refresh_interval_seconds = 72000;
       disable_xma_backfill = true;
       disable_xma_always = false;
      };
      bridge = {
       command_prefix = "!instagram";
       personal_filtering_spaces = true;
       private_chat_protal_meta = true;
       async_events = false;
       split_portals = false;
       resend_bridge_info = false;
       no_bridge_info_state_key = false;
       bridge_matrix_leave = false;
       tag_only_on_create = true;
       only_bridge_tags = [ "m.favourite" "m.lowpriority" ];
       mute_only_on_create = true;
       cleanup_on_logout = {
        enabled = false;
       };
       relay = {
        enabled = false;
       };
       permissions = {
        "*" = "relay";
        "claytonhickey.me" = "user";
        "@clay53:claytonhickey.me" = "admin";
       };
      };
      database = {
       type = "sqlite3-fk-wal";
       uri = "file:/var/lib/${config.services.mautrix-meta.instances.instagram.dataDir}/mautrix-meta.db?_txlock=immediate";
      };
      homeserver = {
       address = config.services.matrix-synapse.settings.public_baseurl;
       domain = config.services.matrix-synapse.settings.server_name;
       software = "standard";
       async_media = false;
       websocket = false;
       ping_interval_seconds = 0;
      };
      appservice = {
       address = "http://localhost:29319";
       hostname = "127.0.0.1";
       port = 29319;
       id = "instagram";
       bot = {
        username = "instagrambot";
        displayname = "Instagram bridge bot";
        avatar = "mxc://maunium.net/DxpVrwwzPUwaUSazpsjXgcKB";
       };
       ephemeral_events = true;
       async_transactions = true;
       username_template = "instagram_{{.}}";
      };
      matrix = {
       message_status_events = false;
       delivery_recepts = false;
       message_error_notices = true;
       sync_direct_chat_list = true;
       federate_rooms = true;
       uplad_file_threshold = 5242880;
      };
      analytics = {
       token = null;
       url = "https://api.segment.io/v1/track";
       user_id = null;
      };
      provisioning = {
       prefix = "/_matrix/provision";
       shard_secret = "generate";
       allow_matrix_auth = true;
       debug_endpoints = false;
      };
      public_media = {
       enabled = false;
      };
      direct_media = {
       enabled = false;
      };
      backfill = {
       enable = true;
       max_initial_messages = 50;
       max_catchup_messages= 500;
       unread_hours_threshold = 720;
       threads = {
        max_initial_messages = 50;
       };
       queue = {
        enabled = false;
       };
      };
      encryption = {
       allow = true;
       default = true;
      };
      logging = {
       min_level = "debug";
       writers = [
        {
         type = "stdout";
         format = "pretty-colored";
        }
       ];
      };
     };
    };
    facebook = {
     enable = true;
     registerToSynapse = true;
     settings = {
      network = {
       mode = "facebook";
       ig_e2ee = false;
       displayname_template = "{{or .DisplayName .Username \"Unknown User\"}}";
       proxy_media = false;
       min_full_reconnect_interval_seconds = 3600;
       force_refresh_interval_seconds = 72000;
       disable_xma_backfill = true;
       disable_xma_always = false;
      };
      bridge = {
       command_prefix = "!facebook";
       personal_filtering_spaces = true;
       private_chat_protal_meta = true;
       async_events = false;
       split_portals = false;
       resend_bridge_info = false;
       no_bridge_info_state_key = false;
       bridge_matrix_leave = false;
       tag_only_on_create = true;
       only_bridge_tags = [ "m.favourite" "m.lowpriority" ];
       mute_only_on_create = true;
       cleanup_on_logout = {
        enabled = false;
       };
       relay = {
        enabled = false;
       };
       permissions = {
        "*" = "relay";
        "claytonhickey.me" = "user";
        "@clay53:claytonhickey.me" = "admin";
       };
      };
      database = {
       type = "sqlite3-fk-wal";
       uri = "file:/var/lib/${config.services.mautrix-meta.instances.facebook.dataDir}/mautrix-meta.db?_txlock=immediate";
      };
      homeserver = {
       address = config.services.matrix-synapse.settings.public_baseurl;
       domain = config.services.matrix-synapse.settings.server_name;
       software = "standard";
       async_media = false;
       websocket = false;
       ping_interval_seconds = 0;
      };
      appservice = {
       address = "http://localhost:29320";
       hostname = "127.0.0.1";
       port = 29320;
       id = "facebook";
       bot = {
        username = "facebookbot";
        displayname = "Facebook bridge bot";
        avatar = "mxc://maunium.net/DxpVrwwzPUwaUSazpsjXgcKB";
       };
       ephemeral_events = true;
       async_transactions = true;
       username_template = "facebook_{{.}}";
      };
      matrix = {
       message_status_events = false;
       delivery_recepts = false;
       message_error_notices = true;
       sync_direct_chat_list = true;
       federate_rooms = true;
       uplad_file_threshold = 5242880;
      };
      analytics = {
       token = null;
       url = "https://api.segment.io/v1/track";
       user_id = null;
      };
      provisioning = {
       prefix = "/_matrix/provision";
       shard_secret = "generate";
       allow_matrix_auth = true;
       debug_endpoints = false;
      };
      public_media = {
       enabled = false;
      };
      direct_media = {
       enabled = false;
      };
      backfill = {
       enable = true;
       max_initial_messages = 50;
       max_catchup_messages= 500;
       unread_hours_threshold = 720;
       threads = {
        max_initial_messages = 50;
       };
       queue = {
        enabled = false;
       };
      };
      encryption = {
       allow = true;
       default = true;
      };
      logging = {
       min_level = "debug";
       writers = [
        {
         type = "stdout";
         format = "pretty-colored";
        }
       ];
      };
     };
    };
   };
  };
 };

 # List packages installed in system profile. To search, run:
 # $ nix search wget
 environment.systemPackages = with pkgs; [
  neovim
  wget
  inetutils
  mtr
  sysstat
  htop
  git
  ocaml
  #nixpkgs-mautrix-nix.mautrix-slack
  #mautrix-gmessages
  mautrix-meta
  mautrix-discord
  ncdu
  tcpdump
  cloudflared
 ];

 systemd = {
  services = {
   ClaytonXYZ = {
    wantedBy = [ "default.target" ];
    description = "claytondoesthings website";
    environment = {
     STATIC_DIR = "${ClaytonXYZ}/s";
     DOMAIN = "https://claytondoesthings.xyz";
     ROCKET_PORT = "5000";
    };
    serviceConfig = {
     Type = "simple";
      ExecStart = ''${ClaytonXYZ}/target/release/clayton_xyz'';
    };
   };
   #iloveu = {
   # wantedBy = [ "default.target" ];
   # description = "iloveu server";
   # serviceConfig = {
   #  Type = "simple";
   #   ExecStart = ''${iloveu.server}/bin/iloveu-server --address 127.0.0.1:5001 --password "N86QVNwNZe!oXz" --transactions-dir /Block/iloveu'';
   # };
   #};
   claytonhickeymeUpdate = {
    description = "update claytonhickeyme website";
    wantedBy = [ "default.target" ];
    path = [ pkgs.git pkgs.ocaml pkgs.nix ];
    environment = {
     NIX_PATH="/root/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
    };
    script = ''#!/bin/sh
     cd /Block/claytonhickey_me
     ./update.sh
    '';
    serviceConfig.Type = "oneshot";
    startAt = "*:0/2";
   };
   #api_claytonhickey_me = {
   # description = "api for claytonhickeyme website";
   # wantedBy = [ "default.target" ];
   # path = [ pkgs.nix pkgs.bash ];
   # environment = {
   #  NIX_PATH="/root/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels";
   #  HOME="/root";
   # };
   # script = ''#!/bin/sh
   #  cd /Block/api_claytonhickey_me
   #  nix run 'github:mitchellh/zig-overlay#master-2025-01-20' --extra-experimental-features nix-command --extra-experimental-features flakes build run
   # '';
   #};
   #mcServer = {
   # description = "Minecraft";
   # wantedBy = [ "default.target" ];
   # path = [ pkgs.jdk21 ];
   # script = ''#!/bin/sh
   #      cd /Block/mc-server
   #      ./start.sh
   # '';
   #};
   #mautrix-slack = {
   # wantedBy = [ "default.target" ];
   # description = "Mautrix-slack";
   # serviceConfig = {
   #  Type = "simple";
   #  User = "mautrix-slack";
   #  ExecStart = ''${nixpkgs-mautrix-nix.mautrix-slack}/bin/mautrix-slack -c /opt/mautrix-slack/slack-config.yaml -r /var/lib/matrix-synapse/slack-registration.yaml'';
   # };
   #};
   #mautrix-gmessages = {
   # wantedBy = [ "default.target" ];
   # description = "Mautrix-gmessages";
   # serviceConfig = {
   #  Type = "simple";
   #  User = "mautrix-gmessages";
   #  ExecStart = ''${pkgs.mautrix-gmessages}/bin/mautrix-gmessages -c /opt/mautrix-gmessages/config.yaml -r /var/lib/matrix-synapse/gmessages-registration.yaml'';
   # };
   #};
   mautrix-discord = {
    wantedBy = [ "default.target" ];
    description = "Mautrix-discord";
    serviceConfig = {
     Type = "simple";
     User = "mautrix-discord";
     ExecStart = ''${pkgs.mautrix-discord}/bin/mautrix-discord -c /opt/mautrix-discord/config.yaml -r /var/lib/matrix-synapse/discord-registration.yaml'';
    };
   };
  };
 };

 users = {
  groups = {
   #mautrix-slack = {};
   #mautrix-gmessages = {};
   mautrix-discord = {};
  };
  users = {
   #mautrix-slack = {
   # isSystemUser = true;
   # home = "/opt/mautrix-slack";
   # group = "mautrix-slack";
   # createHome = true;
   # useDefaultShell = true;
   #};
   #mautrix-gmessages = {
   # isSystemUser = true;
   # home = "/opt/mautrix-gmessages";
   # group = "mautrix-gmessages";
   # createHome = true;
   # useDefaultShell = true;
   #};
   mautrix-discord = {
    isSystemUser = true;
    home = "/opt/mautrix-discord";
    group = "mautrix-discord";
    createHome = true;
    useDefaultShell = true;
   };
  };
 };

 security.acme = {
  acceptTerms = true;
  defaults.email = "clayton@claytondoesthings.xyz";
 };

 nixpkgs.config = {
  allowUnfree = true;
  permittedInsecurePackages = [
    "olm-3.2.16"
   ];
 };

 nix.settings.experimental-features = [ "nix-command" "flakes" ];

 system.stateVersion = "23.05";
}
