{
  stdenv,
  taste,
  configPath,
  versions,
  callPackage,
  linuxPackages,
  linuxPackagesFor,
  fetchFromGitHub,
  lib,
  pkgs,
  buildPackages,
  ogKernelConfigfile ? linuxPackages.kernel.passthru.configfile,
  withUpdateScript ? null,
  packagesExtend ? null,
  cachyOverride,
  extraMakeFlags ? [ ],
  zfsOverride ? { },
  # those are set in their PKGBUILDs
  basicCachy ? true,
  mArch ? null,
  cpuSched ? "cachyos",
  useLTO ? "none",
  ticksHz ? 500,
  tickRate ? "full",
  preempt ? "full",
  hugePages ? "always",
  withDAMON ? false,
  withNTSync ? true,
  withHDR ? true,
  withoutDebug ? false,
  pageSize ? "4k",
  description ? "Linux EEVDF-BORE scheduler Kernel by CachyOS with other patches and improvements",
  # For flakes
  inputs ? { },
  pname ? "unknown",
  # Explicitly accept nixpkgs, falling back to inputs or the system path
  nixpkgs ? inputs.nixpkgs or pkgs.path,
}:

let
  # For revs
  shorter = builtins.substring 0 7;

  # Helps when overriding.
  dropUpdateScript = prevAttrs: { passthru = removeAttrs prevAttrs.passthru [ "updateScript" ]; };

  # Helps when batch-overriding.
  dropAttrsUpdateScript = builtins.mapAttrs (
    _k: v: if (v.passthru.updateScript or null) != null then v.overrideAttrs dropUpdateScript else v
  );

  # Helps when batch-overriding.
  setAttrsPlatforms =
    platforms:
    builtins.mapAttrs (
      _k: v:
      if (v ? "overrideAttrs") then
        v.overrideAttrs (prevAttrs: {
          meta = (prevAttrs.meta or { }) // {
            platforms = lib.lists.intersectLists (prevAttrs.meta.platforms or [ ]) platforms;
            platformsOrig = prevAttrs.meta.platforms or [ ];
            badPlatforms = [ ];
          };
        })
      else
        v
    );

  cachyConfig = {
    inherit
      taste
      versions
      basicCachy
      mArch
      cpuSched
      useLTO
      ticksHz
      tickRate
      preempt
      hugePages
      withDAMON
      withNTSync
      withHDR
      withoutDebug
      description
      withUpdateScript
      pageSize
      ;
  };

  # The three phases of the config
  # - First we apply the changes fromt their PKGBUILD using kconfig;
  # - Then we NIXify it (in the update-script);
  # - Last state is importing the NIXified version for building.
  preparedConfigfile = callPackage ./prepare.nix {
    inherit
      cachyConfig
      stdenv
      kernel
      ogKernelConfigfile
      commonMakeFlags
      ;
  };
  kconfigToNix = callPackage ./lib/kconfig-to-nix.nix {
    configfile = preparedConfigfile;
  };
  linuxConfigTransfomed = import configPath;

  # normalizeKernelName = pname: drv:
  #   drv.overrideAttrs (old: let
  #     ver = old.version or (lib.getVersion old.name or "unknown");
  #   in {
  #     __intentionallyOverridingVersion = true;
  #     pname = (if useLTO != "none" then "${pname}-lto" else pname);
  #     version = ver;
  #     name = "${pname}-${ver}";
  #   });

  # versionSuffix = "+C${shorter versions.config.rev}+P${shorter versions.patches.rev}";

  # kernel =
  #   normalizeKernelName (cachyConfig.taste or "linux")
  #     (callPackage ./kernel.nix {
  #       inherit cachyConfig stdenv kconfigToNix;
  #       kernelPatches = [ ];
  #       configfile = preparedConfigfile;
  #       config = linuxConfigTransfomed;
  #       flakes = inputs.flakes or null;
  #       final = inputs.final or null;
  #       kernelPackages = packagesWithRightPlatforms;
  #     });

  kernel = callPackage ./kernel.nix {
    inherit
      cachyConfig
      pname
      stdenv
      kconfigToNix
      ;
    kernelPatches = [ ];
    configfile = preparedConfigfile;
    config = linuxConfigTransfomed;
    # For tests: Use 'or null' so it doesn't crash if inputs is empty
    flakes = inputs.flakes or null;
    final = inputs.final or null;
    kernelPackages = packagesWithRightPlatforms;
  };

  # Use 'nixpkgs' argument instead of 'inputs.nixpkgs'
  commonMakeFlags = import "${nixpkgs}/pkgs/os-specific/linux/kernel/common-flags.nix" {
    inherit
      lib
      stdenv
      buildPackages
      extraMakeFlags
      ;
  };

  # CachyOS repeating stuff.
  addOurs = finalAttrs: prevAttrs: {
    kernel_configfile = prevAttrs.kernel.configfile;
    zfs_cachyos =
      (finalAttrs.callPackage "${nixpkgs}/pkgs/os-specific/linux/zfs/generic.nix" zfsOverride {
        kernelModuleAttribute = "zfs_cachyos";
        kernelMinSupportedMajorMinor = "1.0";
        kernelMaxSupportedMajorMinor = "99.99";
        enableUnsupportedExperimentalKernel = true;
        inherit (prevAttrs.zfs_2_3) version;
        tests = { };
        maintainers = with lib.maintainers; [
          pedrohlc
        ];
        hash = "";
        extraPatches = [ ];
      }).overrideAttrs
        (prevAttrs: {
          src = fetchFromGitHub {
            owner = "cachyos";
            repo = "zfs";
            inherit (versions.zfs) rev hash;
          };
          postPatch = builtins.replaceStrings [ "grep --quiet '^Linux-M" ] [ "# " ] prevAttrs.postPatch;
        });
    inherit cachyOverride;
  };

  basePackages = linuxPackagesFor kernel;
  packagesWithOurs = basePackages.extend addOurs;
  packagesWithExtend =
    if packagesExtend == null then
      packagesWithOurs
    else
      packagesWithOurs.extend (packagesExtend kernel);
  packagesWithRemovals = removeAttrs packagesWithExtend [
    "zfs"
    "zfs_2_1"
    "zfs_2_2"
    "zfs_2_3"
    "zfs_unstable"
    "lkrg"
    "drbd"
    # these kernelPackages.* are now pkgs.*
    "system76-power"
    "system76-scheduler"
    "perf"
  ];
  packagesWithoutUpdateScript = dropAttrsUpdateScript packagesWithRemovals;
  packagesWithRightPlatforms = setAttrsPlatforms supportedPlatforms packagesWithoutUpdateScript;

  supportedPlatforms = [
    (with lib.systems.inspect.patterns; isx86_64 // isLinux)
    (with lib.systems.inspect.patterns; isx86 // isLinux)
    "x86_64-linux"
    "aarch64-linux"
  ];

  versionSuffix = "+C${shorter versions.config.rev}+P${shorter versions.patches.rev}";
in
packagesWithRightPlatforms
// {
  _description = "Kernel and modules for ${description}";
  _version = "${versions.linux.version}${versionSuffix}";
  inherit (basePackages) kernel; # This one still has the updateScript
}
