{ self }:
let
  inherit (self.inputs.stable) lib;
  # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L111
  generateExtractedLicensingInfos =
    license:
    if (builtins.typeOf license) == "list" then
      builtins.map (_x: generateExtractedLicensingInfos) license
    else
      let
        inherit (license) fullName shortName;
        url = if builtins.hasAttr "url" license then license.url else "NA";
      in
      [
        {
          # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L120
          crossRefs = lib.optional (builtins.hasAttr "url" license) [
            {
              # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L126
              isLive = true;
              inherit (license) url;
            }
          ];
          # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L160
          # We will not parse the detail from derevation content to avoid
          # adding a lot of processing time to this function. As nix derivations 
          # require and/or have a default applied, we can utilise this with confidence.
          extractedText = fullName;
          # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L164
          licenseId = shortName;
          # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L168
          name = fullName;
          # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L172
          seeAlsos = lib.optional (builtins.hasAttr "url" license) license.url;
        }
      ];

  generateLicenseExpression =
    drv:
    if (builtins.typeOf drv.meta.license) == "list" then
      (builtins.concatStringsSep ", " (builtins.map (x: x.fullName) drv.meta.license))
    else
      drv.meta.license.fullName;

  # Recursive function to generate the SBOM for a derivation and its dependencies
  generateSbom =
    drv:
    let
      # Generate the SPDX license expression for the derivation
      license =
        if builtins.hasAttr "license" drv.meta then
          generateLicenseExpression drv.meta.license
        else
          builtins.getAttr "meta" drv.meta.license;

      # Get the derivation's dependencies and their SBOMs

      # DEPENDENCY_OF / BUILD_DEPENDENCY_OF
      dependencies =
        drv.buildInputs ++ drv.propagatedBuildInputs ++ drv.propagatedNativeBuildInputs;

      generatePackages = builtins.map (drv: {
        SPDXID = packageName drv;
        checksums = [
          {
            algorithm = "NIX";
            # /nix/store/b04fryh003f8amrjcs5fv7i3jldr1vja-ripgrep-13.0.0
            checksumValue = generateNixChecksum drv;
          }
        ];
        copyrightText = generateLicenseExpression drv;
      });

      packages = generatePackages dependencies;

      # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L730
      # [ "VARIANT_OF", "COPY_OF", "PATCH_FOR", "TEST_DEPENDENCY_OF", "CONTAINED_BY", "DATA_FILE_OF", "OPTIONAL_COMPONENT_OF", "ANCESTOR_OF", "GENERATES", "CONTAINS", "OPTIONAL_DEPENDENCY_OF", "FILE_ADDED", "REQUIREMENT_DESCRIPTION_FOR", "DEV_DEPENDENCY_OF", "DEPENDENCY_OF", "BUILD_DEPENDENCY_OF", "DESCRIBES", "PREREQUISITE_FOR", "HAS_PREREQUISITE", "PROVIDED_DEPENDENCY_OF", "DYNAMIC_LINK", "DESCRIBED_BY", "METAFILE_OF", "DEPENDENCY_MANIFEST_OF", "PATCH_APPLIED", "RUNTIME_DEPENDENCY_OF", "TEST_OF", "TEST_TOOL_OF", "DEPENDS_ON", "SPECIFICATION_FOR", "FILE_MODIFIED", "DISTRIBUTION_ARTIFACT", "AMENDS", "DOCUMENTATION_OF", "GENERATED_FROM", "STATIC_LINK", "OTHER", "BUILD_TOOL_OF", "TEST_CASE_OF", "PACKAGE_OF", "DESCENDANT_OF", "FILE_DELETED", "EXPANDED_FROM_ARCHIVE", "DEV_TOOL_OF", "EXAMPLE_OF" ]

      # Combine the dependencies into a list

      packageName =
        drv:
        if builtins.hasAttr "name" drv then
          drv.name
        else if builtins.hasAttr "pname" drv then
          drv.pname
        else
          drv.outPath;

      spdxVersion = "SPDX 2.3";
      # // SPDX 2.3

      # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L42

      # Pls no :sadpanda:
      generateNixChecksum =
        drv:
        builtins.head (
          builtins.filter (x: (builtins.stringLength x) == 32) (
            builtins.filter (x: (builtins.typeOf x) != "list") (
              builtins.split "[/-]" drv.outPath
            )
          )
        );

      # https://github.com/spdx/spdx-spec/blob/386ce342a28f12d31b77a549261857eda16f9304/schemas/spdx-schema.json#L74

      SPDXID = packageName drv;
      dataLicense = "CC0-1.0";
      documentComment = "Generated by Nix SPDX generator";

      hasExtractedLicensingInfos = generateExtractedLicensingInfos drv.meta.license;

      name = "${packageName drv}-${drv.version}";

      # Generate the SPDX document for the derivation
      spdxDocument = {
        inherit
          SPDXID
          dataLicense
          documentComment
          hasExtractedLicensingInfos
          spdxVersion
          name
          packages
          ;

        # Packages = [{
        #   inherit packageName packageDownloadLocation;
        #   packageVersion = drv.version;
        #   packageChecksum = drv.meta.sha256 or "";
        #   packageLicenseDeclared = spdxLicense;
        #   packageLicenseConcluded = spdxLicense;
        #   packageLicenseInfoFromFiles = [ ];
        #   packageLicenseComments = "";
        #   packageFilesAnalyzed = false;
        #   packageVerificationCode = "";
        #   packageSupplier = "";
        #   packageOriginator = "";
        #   packageSourceInfo = "";
        #   packageChecksumAlgorithm = "SHA256";
        #   packageHomePage = drv.meta.homepage or "";
        #   packageSummary = drv.meta.description or "";
        #   packageDescription = drv.meta.description or "";
        #   packageComment = "";
        #   packageAttributionText = "";
        #   externalRefs = [ ];
        #   relationships = depList;
        # }];
      };
    in
    spdxDocument;
in
generateSbom
