# SPDX-FileCopyrightText: 2022-2023 Sarah Vaupel <sarah.vaupel@uniworx.de>, Gregor Kleen <gregor@kleen.consulting>
#
# SPDX-License-Identifier: AGPL-3.0-or-later

{
  inputs = {
    haskell-nix = {
      url = "github:input-output-hk/haskell.nix";
    };

    nixpkgs = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      # ref = "6525bbc06a39f26750ad8ee0d40000ddfdc24acb";
      ref = "21.05";
    };
    nixpkgs-recent = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "22.11";
    };
    flake-utils = {
      type = "github";
      owner = "numtide";
      repo = "flake-utils";
      ref = "main";
    };

    encoding = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/encoding.git?ref=uni2work";
      flake = false;
    };
    memcached-binary = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/memcached-binary.git?ref=uni2work";
      flake = false;
    };
    conduit-resumablesink = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/conduit-resumablesink.git?ref=uni2work";
      flake = false;
    };
    HaskellNet-SSL = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/HaskellNet-SSL.git?ref=uni2work";
      flake = false;
    };
    ldap-client = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/ldap-client.git?ref=uni2work";
      flake = false;
    };
    serversession = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/serversession.git?ref=uni2work";
      flake = false;
    };
    xss-sanitize = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/xss-sanitize.git?ref=uni2work";
      flake = false;
    };
    colonnade = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/colonnade.git?ref=uni2work";
      flake = false;
    };
    minio-hs = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/minio-hs.git?ref=uni2work";
      flake = false;
    };
    cryptoids = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/cryptoids.git?ref=uni2work";
      flake = false;
    };
    zip-stream = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/zip-stream.git?ref=uni2work";
      flake = false;
    };
    yesod = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/yesod.git?ref=uni2work";
      flake = false;
    };
    cryptonite = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/cryptonite.git?ref=uni2work";
      flake = false;
    };
    esqueleto = {
      url = "git+https://gitlab.ifi.lmu.de/uni2work/haskell/esqueleto.git?ref=uni2work";
      flake = false;
    };
  };

  outputs = inputs@{ self, nixpkgs, nixpkgs-recent, flake-utils, haskell-nix, ... }: flake-utils.lib.eachSystem ["x86_64-linux"]
    (system:
      let frontendSource = pkgs.lib.sourceByRegex ./. [
            "^(assets|frontend)(/.*)?$"
            "^config(/(favicon\.json|robots\.txt))?$"
            "^(webpack|postcss)\.config\.js$"
            "^karma\.conf\.js$"
            "^(package|jsconfig|\.eslintrc)\.json$"
            "^\.babelrc$"
          ];

          backendSource = pkgs.lib.sourceByRegex ./. [
            "^(\.hlint|package|stack-flake)\.yaml$"
            "^stack\.yaml\.lock$"
            "^config(/(archive-types|mimetypes|personalised-sheet-files-collate|settings\.yml|submission-blacklist|test-settings\.yml|video-types|wordlist\.txt))?$"
            "^routes$"
            "^(assets|app|hlint|load|messages|models|src|templates|test|testdata)(/.*)?$"
          ];

          pkgs = import nixpkgs {
            inherit system overlays;
            config.allowUnfree = true;
          };

          overlays = [
            (final: prev: let
              pkgs-recent = import nixpkgs-recent { inherit system; };
            in {  inherit (pkgs-recent) dockerTools node2nix stack glibcLocalesUtf8 tzdata chromium minio minio-client skopeo; inherit (pkgs-recent.stdenv) fetchurlBoot; })

            (import ./nix/maildev)
            haskell-nix.overlay
            (import ./nix/uniworx { inherit inputs frontendSource backendSource; gitRevision = if self ? rev then self.rev else null; })
            (import ./nix/docker { inherit self; })
            (import ./nix/parse-changelog.nix {})
          ];

          haskellFlake = pkgs.uniworx.flake {};

          inherit (pkgs.lib) recursiveUpdate;
      in {
        packages = haskellFlake.packages // {
          inherit (pkgs) uniworxNodeDependencies uniworxWellKnown uniworxFrontend uniworxDemoDocker uniworxDocker changelogJson;
        };

        apps = haskellFlake.apps // {
          calculateMaterializedSha = flake-utils.lib.mkApp { drv = pkgs.uniworx.stack-nix.passthru.calculateMaterializedSha; exePath = ""; };
          jqChangelogJson = flake-utils.lib.mkApp { drv = pkgs.jqChangelogJson; };
        };

        checks = haskellFlake.checks // {
          uniworxFrontend = pkgs.uniworxFrontend.check;
        };

        devShell = import ./shell.nix { pkgs = self.legacyPackages.${system}; nixpkgsPath = nixpkgs; };

        legacyPackages = pkgs.lib.foldr (overlay: acc: acc // recursiveUpdate (overlay self.legacyPackages.${system} pkgs) pkgs) {} overlays;

        defaultPackage = self.packages.${system}."uniworx:exe:uniworx";
        defaultApp = self.apps.${system}."uniworx:exe:uniworx";
      }
    );
}
