{
  description = "solving a few mathematical optimisation tasks using well-known algorithms (mathematical informatics course semestral project)";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    flake-compat = {
      url = "github:edolstra/flake-compat";
      flake = false;
    };
    nix-filter = {
      url = "github:numtide/nix-filter";
    };
  };

  outputs = {
    self,
    nixpkgs,
    nix-filter,
    ...
  }: let
    projname = "math-optim";

    system.configurationRevision =
      self.rev
      or throw "Refusing to build from a dirty Git tree!";
    nix.registry.nixpkgs.flake = nixpkgs;

    # to work with older version of flakes
    lastModifiedDate =
      self.lastModifiedDate or self.lastModified or "19700101";
    # lastModifiedDate = "19700101";

    # Generate a user-friendly version number.
    version = "v0.0.0";

    # System types to support.
    supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];

    # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
    forAllSystems = nixpkgs.lib.genAttrs supportedSystems;

    # Nixpkgs instantiated for supported system types.
    nixpkgsFor = forAllSystems (system:
      import nixpkgs {
        inherit system;
        overlays = [
          # no overlay imports atm
          # (import ./overlay.nix)
        ];
      });
  in rec {
    formatter = forAllSystems (
      system:
        nixpkgsFor.${system}.alejandra
    );

    packages = forAllSystems (system: let
      pkgs = nixpkgsFor.${system};
      inherit (pkgs) lib overlays; # -> lib = pkgs.lib;overlays = pkgs.overlays;
    in rec {
      math-optim = with pkgs;
        buildGo119Module rec {
          pname = "${projname}";
          buildInputs = [
            go_1_19
            # gcc
            # glibc
            # glibc.static
          ];
          nativeBuildInputs = [pkgconfig];
          # nativeBuildInputs = [go glibc.static];

          overrideModAttrs = _: {
            # GOPROXY = "direct";
            GOFLAGS = "-buildmode=pie -trimpath -mod=readonly -modcacherw";
          };

          inherit version;
          doCheck = false;
          # use go.mod for managing go deps, instead of vendor-only dir
          proxyVendor = true;
          tags = []; # go "-tags" to build with
          ldflags = [
            "-s"
            "-w"
            "-X main.version=${version}"
          ];

          # dont't forget to update vendorSha256 whenever go.mod or go.sum change
          vendorSha256 = "sha256-JNvU72sb0m5bvKz/D6VAGsQiPh2lKt7N2DuhaOp6XA4=";

          # In 'nix develop', we don't need a copy of the source tree
          # in the Nix store.
          src = nix-filter.lib.filter {
            # when in doubt, check out
            # https://github.com/numtide/nix-filter#design-notes
            # tl;dr: it'd be best to include folders, however there are
            # currently issues with that approach.
            root = lib.cleanSource self;
            exclude = [
              ./flake.nix
              ./flake.lock
              ./default.nix
              ./shell.nix
              ./overlay.nix

              ./README.md

              ./.envrc
              ./.drone.star
              ./.gitattributes
              ./.gitignore
              ./.golangci.yml
              ./.editorconfig
              ./.pre-commit-config.yaml

              ./.badges
              # math-optim program output
              ./out
              ./res

              # nix result symlink
              ./result

              # the entire .git folder
              ./.git
            ];
          };

          meta = {
            description = "solving a few mathematical optimisation tasks using well-known algorithms (originally a mathematical informatics course semestral project)";
            homepage = "https://git.dotya.ml/wanderer/math-optim";
            license = lib.licenses.gpl3;
            maintainers = ["wanderer"];
            platforms = lib.platforms.linux ++ lib.platforms.darwin;
          };
        };
      default = math-optim;
    });

    apps = forAllSystems (system: rec {
      math-optim = {
        type = "app";
        program = "${self.packages.${system}.${projname}}/bin/${projname}";
      };
      default = math-optim;
    });

    devShells = forAllSystems (
      system: let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [
            # (import ./overlay.nix)
          ];
        };
        goPkgs = import nixpkgs {
          useFetched = true;
          inherit system;
          overlays =
            self.overlays
            or []
            ++ [
              # (import ./overlay.nix)
            ];
        };
        gob = pkgs.writeShellScriptBin "gob" ''
          cd $(git rev-parse --show-toplevel)
          go build -v ./...
        '';
        gota = pkgs.writeShellScriptBin "gota" ''
          cd $(git rev-parse --show-toplevel)
          go test ./...
        '';
        gogen = pkgs.writeShellScriptBin "gogen" ''
          cd $(git rev-parse --show-toplevel)
          go generate -v ./report
        '';
        upcache = pkgs.writeShellScriptBin "upcache" ''
          ## refs:
          ##   https://fzakaria.com/2020/08/11/caching-your-nix-shell.html
          ##   https://nixos.wiki/wiki/Caching_nix_shell_build_inputs
          nix-store --query --references $(nix-instantiate shell.nix) | \
            xargs nix-store --realise | \
            xargs nix-store --query --requisites | \
            cachix push ${projname}
          nix build --json \
            | jq -r '.[].outputs | to_entries[].value' \
            | cachix push ${projname}
        '';
        add-license = pkgs.writeShellScriptBin "add-license" ''
          go run github.com/google/addlicense@v1.0.0 -v \
            -c "wanderer <a_mirre at utb dot cz>" \
            -l "GPL-3.0-or-later" -s .
        '';
      in {
        default = with pkgs;
          mkShell
          {
            name = "${projname}-" + version;

            dontAutoPatchelf = "";
            GOFLAGS = "-buildmode=pie -trimpath -mod=readonly -modcacherw";
            GOLDFLAGS = "-s -w -X main.version=${version}";
            CGO_CFLAGS = "-g0 -Ofast -mtune=native -flto";
            CGO_LDFLAGS = "-Wl,-O1,-sort-common,-as-needed,-z,relro,-z,now,-flto -pthread";
            # GOLDFLAGS = "-s -w -X main.version=${version} -linkmode external -extldflags -static";
            # CGO_CFLAGS = "-g0 -mtune=native
            # -I${pkgs.glibc.dev}/include
            # ";
            # LDFLAGS = "-L${pkgs.glibc}/lib";
            # CGO_LDFLAGS = "
            # -Wl,-O1,-sort-common,-as-needed,-z,relro,-z,now,-flto -pthread
            # -L${pkgs.glibc}/lib
            # ";
            # GOPROXY = "direct";
            # GOMEMLIMIT = "10GiB";

            shellHook = ''
              echo " -- in math-optim dev shell..."
            '';

            nativeBuildInputs = [
            ];
            packages =
              [
                # use pathed go, as it's (supposed to be) faster with cgo,
                # which will inevitably encountered anyway.
                # goPkgs.go
                go_1_19
                go-tools
                gopls
                gofumpt
                # golangci-lint
                statix
                alejandra
                cachix

                # glibc.static

                ## ad-hoc cmds
                gob
                gota
                gogen
                upcache
                add-license
              ]
              ++ (
                if stdenv.isLinux
                then [
                ]
                else []
              );
          };
      }
    );
  };
}
