<commit_before>{ config, lib, pkgs, ... }:

with lib;

let
  pkg = pkgs.softether;
  cfg = config.services.softether;

in
{

  ###### interface

  options = {

    services.softether = {

      enable = mkEnableOption "SoftEther VPN services";

      vpnserver.enable = mkEnableOption "SoftEther VPN Server";

      vpnbridge.enable = mkEnableOption "SoftEther VPN Bridge";

      vpnclient = {
        enable = mkEnableOption "SoftEther VPN Client";
        up = mkOption {
          type = types.lines;
          default = "";
          description = ''
            Shell commands executed when the Virtual Network Adapter(s) is/are starting.
          '';
        };
        down = mkOption {
          type = types.lines;
          default = "";
          description = ''
            Shell commands executed when the Virtual Network Adapter(s) is/are shutting down.
          '';
        };
      };

      dataDir = mkOption {
        type = types.string;
        default = "${pkg.dataDir}";
        description = ''
          Data directory for SoftEther VPN.
        '';
      };

    };

  };

  ###### implementation

  config = mkIf cfg.enable (

    mkMerge [{
      environment.systemPackages = [
          (pkgs.lib.overrideDerivation pkg (attrs: {
            dataDir = cfg.dataDir;
          }))
        ];
      systemd.services.softether = {
        description = "SoftEther VPN services initial job";
        after = [ "network-interfaces.target" ];
        wantedBy = [ "multi-user.target" ];
        preStart = ''
            for d in vpnserver vpnbridge vpnclient vpncmd; do
                if ! test -e ${cfg.dataDir}/$d; then
                    ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
                    install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
                fi
            done
            rm -rf ${cfg.dataDir}/vpncmd/vpncmd
            ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
        '';
      };
    }

    (mkIf (cfg.vpnserver.enable) {
      systemd.services.vpnserver = {
        description = "SoftEther VPN Server";
        after = [ "network-interfaces.target" ];
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          ExecStart = "${pkg}/bin/vpnserver start";
          ExecStop = "${pkg}/bin/vpnserver stop";
          Type = "forking";
        };
        preStart = ''
            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
            ln -s ${pkg}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
        '';
        postStop = ''
            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
        '';
      };
    })

    (mkIf (cfg.vpnbridge.enable) {
      systemd.services.vpnbridge = {
        description = "SoftEther VPN Bridge";
        after = [ "network-interfaces.target" ];
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          ExecStart = "${pkg}/bin/vpnbridge start";
          ExecStop = "${pkg}/bin/vpnbridge stop";
          Type = "forking";
        };
        preStart = ''
            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
            ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
        '';
        postStop = ''
            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
        '';
      };
    })

    (mkIf (cfg.vpnclient.enable) {
      systemd.services.vpnclient = {
        description = "SoftEther VPN Client";
        after = [ "network-interfaces.target" ];
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          ExecStart = "${pkg}/bin/vpnclient start";
          ExecStop = "${pkg}/bin/vpnclient stop";
          Type = "forking";
        };
        preStart = ''<commit_msg>softether: Fixed problems with using systemd services<commit_after>{ config, lib, pkgs, ... }:

with lib;

let
  pkg = pkgs.softether;
  cfg = config.services.softether;

in
{

  ###### interface

  options = {

    services.softether = {

      enable = mkEnableOption "SoftEther VPN services";

      vpnserver.enable = mkEnableOption "SoftEther VPN Server";

      vpnbridge.enable = mkEnableOption "SoftEther VPN Bridge";

      vpnclient = {
        enable = mkEnableOption "SoftEther VPN Client";
        up = mkOption {
          type = types.lines;
          default = "";
          description = ''
            Shell commands executed when the Virtual Network Adapter(s) is/are starting.
          '';
        };
        down = mkOption {
          type = types.lines;
          default = "";
          description = ''
            Shell commands executed when the Virtual Network Adapter(s) is/are shutting down.
          '';
        };
      };

      dataDir = mkOption {
        type = types.string;
        default = "${pkg.dataDir}";
        description = ''
          Data directory for SoftEther VPN.
        '';
      };

    };

  };

  ###### implementation

  config = mkIf cfg.enable (

    mkMerge [{
      environment.systemPackages = [
          (pkgs.lib.overrideDerivation pkg (attrs: {
            dataDir = cfg.dataDir;
          }))
        ];
      systemd.services."softether-init" = {
        description = "SoftEther VPN services initial task";
        wantedBy = [ "network-interfaces.target" ];
        serviceConfig = {
          Type = "oneshot";
          RemainAfterExit = false;
        };
        script = ''
            for d in vpnserver vpnbridge vpnclient vpncmd; do
                if ! test -e ${cfg.dataDir}/$d; then
                    ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
                    install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
                fi
            done
            rm -rf ${cfg.dataDir}/vpncmd/vpncmd
            ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
        '';
      };
    }

    (mkIf (cfg.vpnserver.enable) {
      systemd.services.vpnserver = {
        description = "SoftEther VPN Server";
        after = [ "softether-init.service" ];
        wantedBy = [ "network-interfaces.target" ];
        serviceConfig = {
          Type = "forking";
          ExecStart = "${pkg}/bin/vpnserver start";
          ExecStop = "${pkg}/bin/vpnserver stop";
        };
        preStart = ''
            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
            ln -s ${pkg}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
        '';
        postStop = ''
            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
        '';
      };
    })

    (mkIf (cfg.vpnbridge.enable) {
      systemd.services.vpnbridge = {
        description = "SoftEther VPN Bridge";
        after = [ "softether-init.service" ];
        wantedBy = [ "network-interfaces.target" ];
        serviceConfig = {
          Type = "forking";
          ExecStart = "${pkg}/bin/vpnbridge start";
          ExecStop = "${pkg}/bin/vpnbridge stop";
        };
        preStart = ''
            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
            ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
        '';
        postStop = ''
            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
        '';
      };
    })

    (mkIf (cfg.vpnclient.enable) {
      systemd.services.vpnclient = {
        description = "SoftEther VPN Client";
        after = [ "softether-init.service" ];
        wantedBy = [ "network-interfaces.target" ];
        serviceConfig = {
          Type = "forking";
          ExecStart = "${pkg}/bin/vpnclient start";
          ExecStop = "${pkg}/bin/vpnclient stop";
        };
        preStart = ''
{'fraction_non_alphanumeric': 0.13500784929356358, 'fraction_numerical': 0.0026164311878597592, 'mean_word_length': 1.7352415026833632, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3825564', 'n_tokens_mistral': 2367, 'n_tokens_neox': 2275, 'n_words': 447}