{ pkgs, config, ... }:
let
  hosts = import ../../hosts.nix;
in
{

  age.secrets = {
    ntfy-loki = {
      file = ../../secrets/ntfy-loki.age;
      owner = "bertof";
    };
  };

  boot = {
    binfmt.emulatedSystems = [
      "armv7l-linux"
      "aarch64-linux"
    ];
    # kernelPackages = pkgs.linuxPackages_latest;
    loader = {
      systemd-boot.enable = true;
      efi.canTouchEfiVariables = true;
    };
  };

  console = {
    font = "Lat2-Terminus16";
    keyMap = "it";
  };

  environment = {
    pathsToLink = [ "/share/zsh" ];
    systemPackages = builtins.attrValues { inherit (pkgs) helix tmux vim; };
  };

  hardware = {
    enableRedistributableFirmware = true;

    # nvidia.package = config.boot.kernelPackages.nvidiaPackages.legacy_470;
    # nvidia.nvidiaPersistenced = true; # HEADLESS
    # nvidia.prime = {
    #   offload.enable = false;
    #   sync.enable = true;
    #   intelBusId = "PCI:0:2:0";
    #   nvidiaBusId = "PCI:1:0:0";
    # };

    opengl = {
      enable = true;
      extraPackages = builtins.attrValues {
        inherit (pkgs)
          intel-media-driver
          libvdpau-va-gl
          vaapiIntel
          vaapiVdpau
          ;
      };
    };

    bluetooth.enable = true;
  };

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

  programs = {
    dconf.enable = true;
    gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
    };
    zsh.enable = true;
  };

  networking = {
    hostName = "loki";
    interfaces.eno1.useDHCP = true;
    # networkmanager.enable = true;
    # useDHCP = false;
  };

  time.timeZone = "Europe/Rome";

  services = {
    # avahi = {
    #   enable = true;
    #   openFirewall = true;
    #   nssmdns4 = true;
    #   publish = {
    #     enable = true;
    #     addresses = true;
    #     domain = true;
    #     userServices = true;
    #     workstation = true;
    #   };
    #   extraServiceFiles = {
    #     ssh = "${pkgs.avahi}/etc/avahi/services/ssh.service";
    #   };
    # };
    # bazarr = { enable = true; openFirewall = true; group = "users"; };
    blueman.enable = true;
    dbus = {
      packages = [ pkgs.dconf ];
      implementation = "broker";
    };
    esphome = {
      enable = true;
      openFirewall = true;
    };
    # fail2ban = { enable = true; bantime-increment.enable = true; };
    gnome.gnome-keyring.enable = true;
    gvfs.enable = true;
    # jackett = { enable = true; openFirewall = true; group = "users"; };
    jellyfin = {
      enable = true;
      openFirewall = true;
      group = "users";
    };
    logind.lidSwitch = "ignore";
    # node-red = { enable = true; openFirewall = true; withNpmAndGcc = true; };
    openssh = {
      enable = true;
      openFirewall = true;
    };
    # plex = { enable = true; openFirewall = true; group = "users"; };
    power-profiles-daemon.enable = true;
    # prowlarr = { enable = true; openFirewall = true; };
    # radarr = { enable = true; openFirewall = true; group = "users"; };
    # samba-wsdd = { enable = true; discovery = true; };
    # samba = {
    #   enable = true;
    #   enableNmbd = true;
    #   enableWinbindd = true;
    #   nsswins = true;
    #   extraConfig = ''
    #     workgroup = WORKGROUP
    #     load printers = no
    #     smb encrypt = required
    #   '';
    #   shares =
    #     let
    #       common = {
    #         "public" = "no";
    #         "writeable" = "yes";
    #         "create mask" = "0700";
    #         "directory mask" = "2700";
    #         "browseable" = "yes";
    #         "guest ok" = "no";
    #         "read only" = "no";
    #         "force group" = "users";
    #       };
    #     in
    #     {
    #       bertof = lib.recursiveUpdate common {
    #         path = "/home/bertof/";
    #         comment = "Bertof samba share";
    #         "force user" = "bertof";
    #         "valid users" = "bertof";
    #       };
    #       tiziano = lib.recursiveUpdate common {
    #         path = "/home/tiziano/";
    #         comment = "Tiziano samba share";
    #         "force user" = "tiziano";
    #         "valid users" = "tiziano";
    #       };
    #       condiviso = lib.recursiveUpdate common {
    #         path = "/mnt/condiviso";
    #         comment = "Samba share condiviso";
    #         "valid users" = "bertof tiziano";
    #         "create mask" = "0770";
    #         "directory mask" = "2770";
    #         "force create mode" = "0660";
    #         "force directory mode" = "2770";
    #       };
    #     };
    # };
    smartd.enable = true;
    # sonarr = { enable = true; openFirewall = true; group = "users"; };
    thermald.enable = true;
    # transmission = {
    #   enable = true;
    #   openFirewall = true;
    #   group = "users";
    #   settings = {
    #     download-dir = "/mnt/condiviso/Torrent";
    #     incomplete-dir = "/mnt/condiviso/Torrent/.incomplete";
    #   };
    # };
    xserver = {
      # enable = true;
      # videoDrivers = [ "nvidia" ];
      # layout = "it";
      # xkbOptions = "eurosign:e;";
      # libinput.enable = true;
    };

    # zoneminder = {
    #   enable = true;
    #   openFirewall = true;
    #   cameras = 3;
    #   hostname = "0.0.0.0";
    #   database = {
    #     username = "zoneminder";
    #     createLocally = true;
    #   };
    # };

    # mysql = {
    #   # enable = true;
    #   ensureUsers = [{
    #     name = "bertof";
    #     ensurePermissions = { "*.*" = "ALL PRIVILEGES"; };
    #   }];
    # };
  };

  users.users = {
    bertof = {
      isNormalUser = true;
      extraGroups = [
        "audio"
        "input"
        # "docker"
        "libvirtd"
        "network"
        "networkmanager"
        "usb"
        "video"
        "wheel"
      ];
      shell = pkgs.zsh;
    };
    tiziano = {
      isNormalUser = true;
      extraGroups = [
        "audio"
        "input"
        "video"
      ];
      openssh.authorizedKeys.keys = [
        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMExwtJFk6HjySrTZwJH67SOHC3hlL28NO4oe2GXsv6k"
      ];
      shell = pkgs.zsh;
    };
    # jellyfin.extraGroups = [ "video" ];
  };

  # services.snapper = {
  #   configs =
  #     let
  #       common = {
  #         TIMELINE_CREATE = true;
  #         TIMELINE_CLEANUP = true;
  #       };
  #     in
  #     {
  #       bertof = lib.recursiveUpdate common { SUBVOLUME = "/home/bertof/"; ALLOW_USERS = [ "bertof" ]; };
  #       tiziano = lib.recursiveUpdate common { SUBVOLUME = "/home/tiziano/"; ALLOW_USERS = [ "tiziano" ]; };
  #       condiviso = lib.recursiveUpdate common { SUBVOLUME = "/mnt/condiviso"; ALLOW_USERS = [ "bertof" "tiziano" ]; };
  #     };
  # };

  networking.firewall = {
    enable = true;
    allowPing = true;
    allowedTCPPorts = [
      445 # SAMBA
      139 # SAMBA
      5357 # SAMBA-WSDD
      8123 # HOME ASSISTANT
      8384 # SYNCTHING
      8385 # SYNCTHING
    ];
    allowedUDPPorts = [
      137 # SYNCTHING
      138 # SYNCTHING
      3702 # SAMBA-WSDD
    ];
    extraCommands = "iptables -t raw -A OUTPUT -p udp -m udp --dport 137 -j CT --helper netbios-ns";
  };

  virtualisation = {
    # docker.enable = true;
    # kvmgt.enable = true;
    # libvirtd.enable = true;
    podman.enable = true;
    # virtualbox.host.enable = true;

    # oci-containers.containers = {
    #   doods2 = {
    #     image = "docker.io/snowzach/doods2:latest";
    #     # environment = { TZ = "Europe/Rome"; };
    #     extraOptions = [ "--pull=always" ];
    #     ports = [ "127.0.0.1:8080:8080" ];
    #     # volumes = [ "/var/lib/hass:/config" "/mnt/raid0/condiviso:/media" ];
    #   };
    # };

  };

  services.home-assistant = {
    enable = true;
    openFirewall = true;
    config = {
      default_config = { };

      homeassistant = {
        name = "Casa";
        latitude = "!secret home-latitude";
        longitude = "!secret home-longitude";
        country = "IT";
        elevation = 17;
        unit_system = "metric";
        time_zone = "Europe/Rome";
        external_url = "https://home-assistant.bertof.net";
        allowlist_external_dirs = [ "/tmp" ];
      };

      http = {
        use_x_forwarded_for = true;
        trusted_proxies = [
          hosts.zerotier.ipv4."baldur.zto"
          hosts.tailscale.ipv4."baldur.tsn"
          "::1"
          "127.0.0.1"
        ];
      };

      automation = "!include automations.yaml";
      scene = "!include scenes.yaml";
      alert = "!include alert.yaml";

      alarm_control_panel = {
        platform = "manual";
        code = "!secret alarm_code";
        trigger_time = 60;
      };

      assist_pipeline = { };
      # bluetooth = { };
      camera = [
        # {
        #   platform = "local_file";
        #   file_path = "/tmp/doods_camera_camera_cancello.jpg";
        #   name = "File DOODS2 Camera cancello";
        # }
        # {
        #   platform = "local_file";
        #   file_path = "/tmp/doods_camera_camera_vialetto.jpg";
        #   name = "File DOODS2 Camera vialetto";
        # }
        # {
        #   platform = "local_file";
        #   file_path = "/tmp/doods_camera_camera_garage.jpg";
        #   name = "File DOODS2 Camera garage";
        # }
      ];
      cloud = { };
      config = { };
      # device_tracker = [{
      #   platform = "bluetooth_tracker";
      #   request_rssi = true;
      # }];
      # image_processing = [
      #   {
      #     platform = "doods";
      #     url = "http://localhost:8080";
      #     detector = "default";
      #     source = [
      #       {
      #         entity_id = "camera.camera_camera_cancello";
      #         name = "DOODS2 Camera cancello";
      #       }
      #       {
      #         entity_id = "camera.camera_camera_vialetto";
      #         name = "DOODS2 Camera vialetto";
      #       }
      #       {
      #         entity_id = "camera.camera_camera_garage";
      #         name = "DOODS2 Camera garage";
      #       }
      #     ];
      #     confidence = 60;
      #     file_out = "/tmp/doods_{{ camera_entity.split('.')[1] }}.jpg";
      #     scan_interval = 5;
      #     labels = [
      #       "bicycle"
      #       "car"
      #       "cat"
      #       "dog"
      #       "person"
      #       "truck"
      #     ];
      #   }
      # ];
      # esphome = { };
      frontend = { };
      google_assistant = {
        project_id = "home-assistant-390217";
        report_state = true;
        service_account = "!include google-service-account.json";
        exposed_domains = [
          "alarm_control_panel"
          "button"
          "camera"
          "climate"
          "cover"
          "fan"
          "group"
          "humidifier"
          "input_boolean"
          "input_button"
          "input_select"
          "light"
          "lock"
          "media_player"
          "scene"
          "script"
          "select"
          "switch"
          "vacuum"
        ];
      };
      history = { };
      logbook = { };
      # logger.default = "debug";
      logger.default = "info";
      # "map" = { };
      mobile_app = { };
      notify = [
        # { platform = "telegram"; name = "t_filippo"; chat_id = "!secret filippo_t_chat_id"; }
        # { platform = "telegram"; name = "t_famiglia"; chat_id = "!secret famiglia_t_chat_id"; }
      ];
      recorder.purge_keep_days = 30;
      script = "!include scripts.yaml";
      shopping_list = { };
      sun = { };
      system_health = { };
      # telegram_bot = [{
      #   # platform = "polling";
      #   platform = "webhooks";
      #   api_key = "!secret telegram_api_key";
      #   allowed_chat_ids = [
      #     "!secret filippo_t_chat_id"
      #     "!secret famiglia_t_chat_id"
      #   ];
      # }];
      tts = [
        {
          platform = "google_translate";
          language = "it";
          # tld = "it";
        }
      ];
    };
    configDir = "/var/lib/hass";
    configWritable = true;
    extraPackages = ps: with ps; [ securetar ];
    extraComponents = [
      "default_config"

      "alert"
      "analytics"
      "androidtv"
      "androidtv_remote"
      "bayesian"
      "binary_sensor"
      "blueprint"
      # "bluetooth_le_tracker"
      # "bluetooth_tracker"
      "button"
      "camera"
      "cast"
      "caldav"
      "calendar"
      "citybikes"
      "configurator"
      # "coronavirus"
      "cover"
      "default_config"
      "derivative"
      "device_automation"
      "device_sun_light_trigger"
      "device_tracker"
      "dlib_face_detect"
      "dlib_face_identify"
      "dlna_dmr"
      "dlna_dms"
      "esphome"
      "flux"
      "gdacs"
      "google"
      "google_translate"
      "group"
      "hassio"
      "jellyfin"
      "local_file"
      "media_player"
      "met"
      "meteoalarm"
      "network"
      # "nextcloud"
      "nmap_tracker"
      "notify"
      "open_meteo"
      "ping"
      "plex"
      "proximity"
      "radarr"
      "radio_browser"
      "random"
      "scene"
      "schedule"
      "script"
      "sonarr"
      "speedtestdotnet"
      "spotify"
      "tcp"
      # "telegram"
      # "telegram_bot"
      "template"
      "threshold"
      "transmission"
      "tod" # times of the day
      "trend"
      "tuya"
      "upnp"
      "wake_on_lan"
      "wled"
      "workday"
      "zha"
      "zoneminder"
    ];
  };

  services.prometheus = {
    enable = true;
    exporters = {
      node = {
        enable = true;
        enabledCollectors = [ "systemd" ];
      };
      process = {
        enable = true;
        settings.process_names = [
          # Remove nix store path from process name
          {
            name = "{{.Matches.Wrapped}} {{ .Matches.Args }}";
            cmdline = [ "^/nix/store[^ ]*/(?P<Wrapped>[^ /]*) (?P<Args>.*)" ];
          }
        ];
      };
      systemd.enable = true;
    };
    globalConfig = {
      scrape_interval = "10s";
    };
    scrapeConfigs = [
      {
        job_name = "node";
        static_configs = [
          { targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ]; }
        ];
      }
      {
        job_name = "process";
        static_configs = [
          { targets = [ "localhost:${toString config.services.prometheus.exporters.process.port}" ]; }
        ];
      }
      {
        job_name = "systemd";
        static_configs = [
          { targets = [ "localhost:${toString config.services.prometheus.exporters.systemd.port}" ]; }
        ];
      }
    ];
    retentionTime = "15d";
  };

  security.sudo.extraConfig = ''
    Defaults pwfeedback
  '';

  system.stateVersion = "22.11";
}
