/*
Some utility commands:
- `nix flake update --commit-lock-file`
- `nix flake lock update-input <input>`
- `nix build .#ji-chan` or `nix build .`
- `nix run .#ji-chan` or `nix run .`
*/

{
  description = "Discord bot for the Tegaki Tuesday handwriting challenge";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
  };

  outputs = { self, nixpkgs, rust-overlay }:
    let
      overlays = [ (import rust-overlay) ];
      system = "x86_64-linux";
      pkgs = import nixpkgs {
        inherit system overlays;
      };
    in {
      devShells.${system}.default = with pkgs; mkShell {
        packages = [
          (pkgs.rust-bin.stable.latest.default.override {
            extensions = [ "rust-src" ];
          })
          cargo-edit
          bacon
        ];
        inputsFrom = with self.packages.${system}; [ ji-chan ];
      };
      packages.${system} = {
        default = self.packages.${system}.ji-chan;
        ji-chan = pkgs.rustPlatform.buildRustPackage {
          src = ./.;
          pname = "ji-chan";
          version = "0.1.0";
          nativeBuildInputs = with pkgs; [ pkg-config ];
          buildInputs = with pkgs; [ openssl ];
          # rustPlatform.fetchCargoTarball is deprecated in favor of rustPlatform.fetchCargoVendor.
          useFetchCargoVendor = true;
          cargoHash = "sha256-RNQRqW4BA6hixj4i1xBzs4d7MoQL6e+l4AeBrGhQ+nQ=";
          meta = with nixpkgs.lib; {
            homepage = "https://tegakituesday.com";
            description = "Discord bot for the Tegaki Tuesday handwriting challenge";
            license = [ licenses.gpl3 ];
            platforms = [ system ];
            maintainers = with maintainers; [ elnudev ];
          };
        };
      };
      nixosModules.default = { config, ... }: let
        lib = nixpkgs.lib;
      in {
        options.services.ji-chan = {
          enable = lib.mkEnableOption (lib.mdDoc "ji-chan service");
          package = lib.mkOption {
            type = lib.types.package;
            default = self.packages.${system}.ji-chan;
            defaultText = "pkgs.ji-chan";
            description = lib.mdDoc ''
              The ji-chan package that should be used.
            '';
          };
          domain = lib.mkOption {
            type = lib.types.str;
            default = "tegakituesday.com";
            description = lib.mdDoc ''
              Website domain
            '';
          };
          token = lib.mkOption {
            type = lib.types.str;
            description = lib.mdDoc ''
              Discord token
            '';
          };
          prefix = lib.mkOption {
            type = lib.types.str;
            default = "-h ";
            description = lib.mdDoc ''
              Traditional text command prefix, including space, if any
            '';
          };
          hugo = lib.mkOption {
            type = lib.types.str;
            description = lib.mdDoc ''
              Path to Hugo project where site rebuilds
            '';
          };
          guildData = lib.mkOption {
            type = lib.types.package;
            description = lib.mdDoc ''
              Guild data JSON file
            '';
          };
        };
        config.systemd.services.ji-chan = let
          cfg = config.services.ji-chan;
          pkg = self.packages.${system}.ji-chan;
        in lib.mkIf cfg.enable {
          description = pkg.meta.description;
          after = [ "network.target" ];
          wantedBy = [ "network.target" ];
          serviceConfig = {
            ExecStart = ''
              ${cfg.package}/bin/ji-chan --domain ${cfg.domain} --token ${cfg.token} --prefix "${builtins.replaceStrings ["\""] ["\\\""] cfg.prefix}" --hugo ${cfg.hugo} --guilds ${cfg.guildData}
            '';
            Restart = "always";
            DynamicUser = true;
          };
        };
      };
    };
}