{ config, lib, pkgs, ... }:

let
  cfg = config.services.mediawiki;
in
{
  c3d2.deployment.server = "server10";

  microvm.mem = 1024;

  networking = {
    firewall.allowedTCPPorts = [ 80 443 ]; # httpd, not nginx :(
    hostName = "mediawiki";
  };

  services = {
    logrotate.checkConfig = false;

    mediawiki = {
      enable = true;
      virtualHost = {
        adminAddr = "no-reply@c3d2.de";
        enableACME = true;
        forceSSL = true;
        hostName = "wiki.c3d2.de";
        extraConfig = ''
          RewriteEngine On
          RewriteRule ^/w/(.*).php /$1.php [L,QSA]
          RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
          RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
          RewriteCond %{REQUEST_URI} !^/images
          RewriteRule ^(.*) /index.php/$1 [L,QSA]
        '';
      };
      #skins = {
      #      Vector = "${config.services.mediawiki.package}/share/mediawiki/skins/Vector";
      #      Hector = "${config.services.mediawiki.package}/share/mediawiki/skins/Hector";
      #};
      name = "C3D2";

      extraConfig = ''
        $wgArticlePath = '/$1';

        $wgShowExceptionDetails = true;
        $wgDBserver = "${config.services.mediawiki.database.socket}";
        $wgDBmwschema       = "mediawiki";

        $wgLogo =  "https://www.c3d2.de/images/ck.png";
        $wgEmergencyContact = "wiki@c3d2.de";
        $wgPasswordSender   = "wiki@c3d2.de";
        $wgLanguageCode = "de";

        $wgGroupPermissions['*']['edit'] = false;
        $wgGroupPermissions['user']['edit'] = true;
        $wgGroupPermissions['sysop']['interwiki'] = true;
        $wgGroupPermissions['sysop']['userrights'] = true;

        define("NS_INTERN", 100);
        define("NS_INTERN_TALK", 101);

        $wgExtraNamespaces[NS_INTERN] = "Intern";
        $wgExtraNamespaces[NS_INTERN_TALK] = "Intern_Diskussion";

        $wgGroupPermissions['intern']['move']             = true;
        $wgGroupPermissions['intern']['move-subpages']    = true;
        $wgGroupPermissions['intern']['move-rootuserpages'] = true; // can move root userpages
        $wgGroupPermissions['intern']['read']             = true;
        $wgGroupPermissions['intern']['edit']             = true;
        $wgGroupPermissions['intern']['createpage']       = true;
        $wgGroupPermissions['intern']['createtalk']       = true;
        $wgGroupPermissions['intern']['writeapi']         = true;
        $wgGroupPermissions['intern']['upload']           = true;
        $wgGroupPermissions['intern']['reupload']         = true;
        $wgGroupPermissions['intern']['reupload-shared']  = true;
        $wgGroupPermissions['intern']['minoredit']        = true;
        $wgGroupPermissions['intern']['purge']            = true; // can use ?action=purge without clicking "ok"
        $wgGroupPermissions['intern']['sendemail']        = true;

        $wgNamespacePermissionLockdown[NS_INTERN]['*'] = array('intern');
        $wgNamespacePermissionLockdown[NS_INTERN_TALK]['*'] = array('intern');

        define("NS_I4R", 102);
        define("NS_I4R_TALK", 103);
        $wgExtraNamespaces[NS_I4R] = "IT4Refugees";
        $wgExtraNamespaces[NS_I4R_TALK] = "IT4Refugees_Diskussion";
        $wgGroupPermissions['i4r']['move']             = true;
        $wgGroupPermissions['i4r']['move-subpages']    = true;
        $wgGroupPermissions['i4r']['move-rootuserpages'] = true; // can move root userpages
        $wgGroupPermissions['i4r']['read']             = true;
        $wgGroupPermissions['i4r']['edit']             = true;
        $wgGroupPermissions['i4r']['createpage']       = true;
        $wgGroupPermissions['i4r']['createtalk']       = true;
        $wgGroupPermissions['i4r']['writeapi']         = true;
        $wgGroupPermissions['i4r']['upload']           = true;
        $wgGroupPermissions['i4r']['reupload']         = true;
        $wgGroupPermissions['i4r']['reupload-shared']  = true;
        $wgGroupPermissions['i4r']['minoredit']        = true;
        $wgGroupPermissions['i4r']['purge']            = true; // can use ?action=purge without clicking "ok"
        $wgGroupPermissions['i4r']['sendemail']        = true;
        $wgNamespacePermissionLockdown[NS_I4R]['*'] = array('i4r');
        $wgNamespacePermissionLockdown[NS_I4R_TALK]['*'] = array('i4r');

        $wgGroupPermissions['sysop']['deletelogentry'] = true;
        $wgGroupPermissions['sysop']['deleterevision'] = true;

        wfLoadExtension('ConfirmEdit/QuestyCaptcha');
        $wgCaptchaClass = 'QuestyCaptcha';
        $wgCaptchaQuestions[] = array( 'question' => 'How is C3D2 logo in ascii?', 'answer' => '<<</>>' );

        $wgEnableAPI = true;
        $wgAllowUserCss = true;
        $wgUseAjax = true;
        $wgEnableMWSuggest = true;

        //TODO what about $wgUpgradeKey ?

        $wgScribuntoDefaultEngine = 'luastandalone';

        # LDAP
        $LDAPProviderDomainConfigs = "${config.sops.secrets."mediawiki/ldapprovider".path}";
        $wgPluggableAuth_EnableLocalLogin = true;
      '';
      # see https://extdist.wmflabs.org/dist/extensions/ for list of extensions
      # save them on https://web.archive.org/save and copy the final URL below
      extensions = {
        Cite = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203658/https://extdist.wmflabs.org/dist/extensions/Cite-REL1_38-d40993e.tar.gz";
          sha256 = "sha256-dziMo6sH4yMPjnDtt0TXiGBxE5uGRJM+scwdeuer5sM=";
        };
        CiteThisPage = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203556/https://extdist.wmflabs.org/dist/extensions/CiteThisPage-REL1_38-bb4881c.tar.gz";
          sha256 = "sha256-sTZMCLlOkQBEmLiFz2BQJpWRxSDbpS40EZQ+f/jFjxI=";
        };
        ConfirmEdit = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203619/https://extdist.wmflabs.org/dist/extensions/ConfirmEdit-REL1_38-50f4dfd.tar.gz";
          sha256 = "sha256-babZDzcQDE446TBuGW/olbt2xRbPjk+5o3o9DUFlCxk=";
        };
        #DynamicPageList = pkgs.fetchzip {
        #  url = "https://web.archive.org/web/20220627203129/https://extdist.wmflabs.org/dist/extensions/DynamicPageList-REL1_38-3b7a26d.tar.gz";
        #  sha256 = "sha256-WjVLks0Q9hSN2poqbKzTJhvOXog7UHJqjY2WJ4Uc64o=";
        #};
        Lockdown = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203048/https://extdist.wmflabs.org/dist/extensions/Lockdown-REL1_38-1915db4.tar.gz";
          sha256 = "sha256-YCYsjh/3g2P8oT6IomP3UWjOoggH7jYjiiix7poOYnA=";
        };
        intersection = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203336/https://extdist.wmflabs.org/dist/extensions/intersection-REL1_38-8525097.tar.gz";
          sha256 = "sha256-shgA0XLG6pgikqldOfda40hV9zC1eBp+NalGhevFq2Q=";
        };
        Interwiki = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220617074130/https://extdist.wmflabs.org/dist/extensions/Interwiki-REL1_38-223bbf8.tar.gz";
          sha256 = "sha256-A4tQuISJNzzXPXJXv9N1jMat1VuZ7khYzk2jxoUqzIk=";
        };
        # requires PluggableAuth
        LDAPAuthentication2 = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220807184305/https://extdist.wmflabs.org/dist/extensions/LDAPAuthentication2-master-6bc5848.tar.gz";
          sha256 = "sha256-32xUhahDObS1S9vYJn61HsbpqyFuL0UAsV5+rmH3iWo=";
        };
        LDAPProvider = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220806214957/https://extdist.wmflabs.org/dist/extensions/LDAPProvider-master-80f8cc8.tar.gz";
          sha256 = "sha256-Y59otw6onknVsjRhyH7L7I0MwnBkvQtuzwpj7c0GZzc=";
        };
        ParserFunctions = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203519/https://extdist.wmflabs.org/dist/extensions/ParserFunctions-REL1_38-bc6a7c6.tar.gz";
          sha256 = "sha256-iDv4VSSFnTKEhvlVQcHHVp2hSWwDbv6jNCq1kOGuswo=";
        };
        PluggableAuth = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220807185047/https://extdist.wmflabs.org/dist/extensions/PluggableAuth-REL1_38-126bad8.tar.gz";
          sha256 = "sha256-cdJdhj7+qisVVePuyKDu6idoUy0+gYo3zMN0y6weH84=";
        };
        Scribunto = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627202748/https://extdist.wmflabs.org/dist/extensions/Scribunto-REL1_38-9b9271a.tar.gz";
          sha256 = "sha256-4sy2ZCnDFzx43WzfS4Enh+I0o0+sFl1RnNV4xGiyU0k=";
        };
        SyntaxHightlight = pkgs.fetchzip {
          url = "https://web.archive.org/web/20220627203440/https://extdist.wmflabs.org/dist/extensions/SyntaxHighlight_GeSHi-REL1_38-79031cd.tar.gz";
          sha256 = "sha256-r1NgrhSratleQ356imxmF7KmAANvWvKpAgnLkm8IdKY=";
        };
      };
      passwordFile = config.sops.secrets."mediawiki/adminPassword".path;
      database = {
        type = "postgres";
        socket = "/run/postgresql";
        user = "mediawiki";
        name = "mediawiki";
      };
      uploadsDir = "/var/lib/mediawiki/uploads";
    };

    phpfpm.phpPackage = pkgs.php.buildEnv {
      extensions = { all, enabled }: enabled ++ (with all; [ apcu ]);
    };

    postgresql = {
      enable = true;
      authentication = lib.mkForce ''
        # TYPE  DATABASE        USER            ADDRESS                 METHOD
        local   all             all                                     trust
        host    all             all             127.0.0.1/32            trust
        host    all             all             10.233.2.1/32           trust
        host    all             all             ::1/128                 trust
      '';
      enableTCPIP = true;
      ensureDatabases = [ cfg.database.name ];
      ensureUsers = [{
        name = cfg.database.user;
        ensurePermissions = { "DATABASE ${cfg.database.name}" = "ALL PRIVILEGES"; };
      }];
      package = pkgs.postgresql_15;
      upgrade.stopServices = [ "httpd" "phpfpm-mediawiki" ];
    };
  };

  sops = {
    age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
    defaultSopsFile = ./secrets.yaml;
    secrets = {
      "mediawiki/adminPassword" = {
        owner = config.systemd.services.mediawiki-init.serviceConfig.User;
      };
      "mediawiki/ldapprovider" = {
        owner = config.systemd.services.mediawiki-init.serviceConfig.User;
      };
      "mediawiki/secretKey" = {
        owner = config.systemd.services.mediawiki-init.serviceConfig.User;
        path = "/var/lib/mediawiki/secret.key";
      };
      "mediawiki/upgradeKey" = {
        owner = config.systemd.services.mediawiki-init.serviceConfig.User;
      };
    };
  };

  system.stateVersion = "22.05";

  systemd.services.mediawiki-init = {
    after = [ "postgresql.service" ];
    requires = [ "postgresql.service" ];
  };
}
