# This file originates from node2nix

{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile, writeShellScript}:

let
  # Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master
  utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux;

  python = if nodejs ? python then nodejs.python else python2;

  # Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
  tarWrapper = runCommand "tarWrapper" {} ''
    mkdir -p $out/bin

    cat > $out/bin/tar <<EOF
    #! ${stdenv.shell} -e
    $(type -p tar) "\$@" --warning=no-unknown-keyword --delay-directory-restore
    EOF

    chmod +x $out/bin/tar
  '';

  # Function that generates a TGZ file from a NPM project
  buildNodeSourceDist =
    { name, version, src, ... }:

    stdenv.mkDerivation {
      name = "node-tarball-${name}-${version}";
      inherit src;
      buildInputs = [ nodejs ];
      buildPhase = ''
        export HOME=$TMPDIR
        tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts)
      '';
      installPhase = ''
        mkdir -p $out/tarballs
        mv $tgzFile $out/tarballs
        mkdir -p $out/nix-support
        echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
      '';
    };

  # Common shell logic
  installPackage = writeShellScript "install-package" ''
    installPackage() {
      local packageName=$1 src=$2

      local strippedName

      local DIR=$PWD
      cd $TMPDIR

      unpackFile $src

      # Make the base dir in which the target dependency resides first
      mkdir -p "$(dirname "$DIR/$packageName")"

      if [ -f "$src" ]
      then
          # Figure out what directory has been unpacked
          packageDir="$(find . -maxdepth 1 -type d | tail -1)"

          # Restore write permissions to make building work
          find "$packageDir" -type d -exec chmod u+x {} \;
          chmod -R u+w "$packageDir"

          # Move the extracted tarball into the output folder
          mv "$packageDir" "$DIR/$packageName"
      elif [ -d "$src" ]
      then
          # Get a stripped name (without hash) of the source directory.
          # On old nixpkgs it's already set internally.
          if [ -z "$strippedName" ]
          then
              strippedName="$(stripHash $src)"
          fi

          # Restore write permissions to make building work
          chmod -R u+w "$strippedName"

          # Move the extracted directory into the output folder
          mv "$strippedName" "$DIR/$packageName"
      fi

      # Change to the package directory to install dependencies
      cd "$DIR/$packageName"
    }
  '';

  # Bundle the dependencies of the package
  #
  # Only include dependencies if they don't exist. They may also be bundled in the package.
  includeDependencies = {dependencies}:
    lib.optionalString (dependencies != []) (
      ''
        mkdir -p node_modules
        cd node_modules
      ''
      + (lib.concatMapStrings (dependency:
        ''
          if [ ! -e "${dependency.packageName}" ]; then
              ${composePackage dependency}
          fi
        ''
      ) dependencies)
      + ''
        cd ..
      ''
    );

  # Recursively composes the dependencies of a package
  composePackage = { name, packageName, src, dependencies ? [], ... }@args:
    builtins.addErrorContext "while evaluating node package '${packageName}'" ''
      installPackage "${packageName}" "${src}"
      ${includeDependencies { inherit dependencies; }}
      cd ..
      ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
    '';

  pinpointDependencies = {dependencies, production}:
    let
      pinpointDependenciesFromPackageJSON = writeTextFile {
        name = "pinpointDependencies.js";
        text = ''
          var fs = require('fs');
          var path = require('path');

          function resolveDependencyVersion(location, name) {
              if(location == process.env['NIX_STORE']) {
                  return null;
              } else {
                  var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");

                  if(fs.existsSync(dependencyPackageJSON)) {
                      var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));

                      if(dependencyPackageObj.name == name) {
                          return dependencyPackageObj.version;
                      }
                  } else {
                      return resolveDependencyVersion(path.resolve(location, ".."), name);
                  }
              }
          }

          function replaceDependencies(dependencies) {
              if(typeof dependencies == "object" && dependencies !== null) {
                  for(var dependency in dependencies) {
                      var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);

                      if(resolvedVersion === null) {
                          process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
                      } else {
                          dependencies[dependency] = resolvedVersion;
                      }
                  }
              }
          }

          /* Read the package.json configuration */
          var packageObj = JSON.parse(fs.readFileSync('./package.json'));

          /* Pinpoint all dependencies */
          replaceDependencies(packageObj.dependencies);
          if(process.argv[2] == "development") {
              replaceDependencies(packageObj.devDependencies);
          }
          else {
              packageObj.devDependencies = {};
          }
          replaceDependencies(packageObj.optionalDependencies);
          replaceDependencies(packageObj.peerDependencies);

          /* Write the fixed package.json file */
          fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
        '';
      };
    in
    ''
      node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}

      ${lib.optionalString (dependencies != [])
        ''
          if [ -d node_modules ]
          then
              cd node_modules
              ${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
              cd ..
          fi
        ''}
    '';

  # Recursively traverses all dependencies of a package and pinpoints all
  # dependencies in the package.json file to the versions that are actually
  # being used.

  pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
    ''
      if [ -d "${packageName}" ]
      then
          cd "${packageName}"
          ${pinpointDependencies { inherit dependencies production; }}
          cd ..
          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
      fi
    '';

  # Extract the Node.js source code which is used to compile packages with
  # native bindings
  nodeSources = runCommand "node-sources" {} ''
    tar --no-same-owner --no-same-permissions -xf ${nodejs.src}
    mv node-* $out
  '';

  # Script that adds _integrity fields to all package.json files to prevent NPM from consulting the cache (that is empty)
  addIntegrityFieldsScript = writeTextFile {
    name = "addintegrityfields.js";
    text = ''
      var fs = require('fs');
      var path = require('path');

      function augmentDependencies(baseDir, dependencies) {
          for(var dependencyName in dependencies) {
              var dependency = dependencies[dependencyName];

              // Open package.json and augment metadata fields
              var packageJSONDir = path.join(baseDir, "node_modules", dependencyName);
              var packageJSONPath = path.join(packageJSONDir, "package.json");

              if(fs.existsSync(packageJSONPath)) { // Only augment packages that exist. Sometimes we may have production installs in which development dependencies can be ignored
                  console.log("Adding metadata fields to: "+packageJSONPath);
                  var packageObj = JSON.parse(fs.readFileSync(packageJSONPath));

                  if(dependency.integrity) {
                      packageObj["_integrity"] = dependency.integrity;
                  } else {
                      packageObj["_integrity"] = "sha1-000000000000000000000000000="; // When no _integrity string has been provided (e.g. by Git dependencies), add a dummy one. It does not seem to harm and it bypasses downloads.
                  }

                  if(dependency.resolved) {
                      packageObj["_resolved"] = dependency.resolved; // Adopt the resolved property if one has been provided
                  } else {
                      packageObj["_resolved"] = dependency.version; // Set the resolved version to the version identifier. This prevents NPM from cloning Git repositories.
                  }

                  if(dependency.from !== undefined) { // Adopt from property if one has been provided
                      packageObj["_from"] = dependency.from;
                  }

                  fs.writeFileSync(packageJSONPath, JSON.stringify(packageObj, null, 2));
              }

              // Augment transitive dependencies
              if(dependency.dependencies !== undefined) {
                  augmentDependencies(packageJSONDir, dependency.dependencies);
              }
          }
      }

      if(fs.existsSync("./package-lock.json")) {
          var packageLock = JSON.parse(fs.readFileSync("./package-lock.json"));

          if(![1, 2].includes(packageLock.lockfileVersion)) {
            process.stderr.write("Sorry, I only understand lock file versions 1 and 2!\n");
            process.exit(1);
          }

          if(packageLock.dependencies !== undefined) {
              augmentDependencies(".", packageLock.dependencies);
          }
      }
    '';
  };

  # Reconstructs a package-lock file from the node_modules/ folder structure and package.json files with dummy sha1 hashes
  reconstructPackageLock = writeTextFile {
    name = "reconstructpackagelock.js";
    text = ''
      var fs = require('fs');
      var path = require('path');

      var packageObj = JSON.parse(fs.readFileSync("package.json"));

      var lockObj = {
          name: packageObj.name,
          version: packageObj.version,
          lockfileVersion: 2,
          requires: true,
          packages: {
              "": {
                  name: packageObj.name,
                  version: packageObj.version,
                  license: packageObj.license,
                  bin: packageObj.bin,
                  dependencies: packageObj.dependencies,
                  engines: packageObj.engines,
                  optionalDependencies: packageObj.optionalDependencies
              }
          },
          dependencies: {}
      };

      function augmentPackageJSON(filePath, packages, dependencies) {
          var packageJSON = path.join(filePath, "package.json");
          if(fs.existsSync(packageJSON)) {
              var packageObj = JSON.parse(fs.readFileSync(packageJSON));
              packages[filePath] = {
                  version: packageObj.version,
                  integrity: "sha1-000000000000000000000000000=",
                  dependencies: packageObj.dependencies,
                  engines: packageObj.engines,
                  optionalDependencies: packageObj.optionalDependencies
              };
              dependencies[packageObj.name] = {
                  version: packageObj.version,
                  integrity: "sha1-000000000000000000000000000=",
                  dependencies: {}
              };
              processDependencies(path.join(filePath, "node_modules"), packages, dependencies[packageObj.name].dependencies);
          }
      }

      function processDependencies(dir, packages, dependencies) {
          if(fs.existsSync(dir)) {
              var files = fs.readdirSync(dir);

              files.forEach(function(entry) {
                  var filePath = path.join(dir, entry);
                  var stats = fs.statSync(filePath);

                  if(stats.isDirectory()) {
                      if(entry.substr(0, 1) == "@") {
                          // When we encounter a namespace folder, augment all packages belonging to the scope
                          var pkgFiles = fs.readdirSync(filePath);

                          pkgFiles.forEach(function(entry) {
                              if(stats.isDirectory()) {
                                  var pkgFilePath = path.join(filePath, entry);
                                  augmentPackageJSON(pkgFilePath, packages, dependencies);
                              }
                          });
                      } else {
                          augmentPackageJSON(filePath, packages, dependencies);
                      }
                  }
              });
          }
      }

      processDependencies("node_modules", lockObj.packages, lockObj.dependencies);

      fs.writeFileSync("package-lock.json", JSON.stringify(lockObj, null, 2));
    '';
  };

  # Script that links bins defined in package.json to the node_modules bin directory
  # NPM does not do this for top-level packages itself anymore as of v7
  linkBinsScript = writeTextFile {
    name = "linkbins.js";
    text = ''
      var fs = require('fs');
      var path = require('path');

      var packageObj = JSON.parse(fs.readFileSync("package.json"));

      var nodeModules = Array(packageObj.name.split("/").length).fill("..").join(path.sep);

      if(packageObj.bin !== undefined) {
          fs.mkdirSync(path.join(nodeModules, ".bin"))

          if(typeof packageObj.bin == "object") {
              Object.keys(packageObj.bin).forEach(function(exe) {
                  if(fs.existsSync(packageObj.bin[exe])) {
                      console.log("linking bin '" + exe + "'");
                      fs.symlinkSync(
                          path.join("..", packageObj.name, packageObj.bin[exe]),
                          path.join(nodeModules, ".bin", exe)
                      );
                  }
                  else {
                      console.log("skipping non-existent bin '" + exe + "'");
                  }
              })
          }
          else {
              if(fs.existsSync(packageObj.bin)) {
                  console.log("linking bin '" + packageObj.bin + "'");
                  fs.symlinkSync(
                      path.join("..", packageObj.name, packageObj.bin),
                      path.join(nodeModules, ".bin", packageObj.name.split("/").pop())
                  );
              }
              else {
                  console.log("skipping non-existent bin '" + packageObj.bin + "'");
              }
          }
      }
      else if(packageObj.directories !== undefined && packageObj.directories.bin !== undefined) {
          fs.mkdirSync(path.join(nodeModules, ".bin"))

          fs.readdirSync(packageObj.directories.bin).forEach(function(exe) {
              if(fs.existsSync(path.join(packageObj.directories.bin, exe))) {
                  console.log("linking bin '" + exe + "'");
                  fs.symlinkSync(
                      path.join("..", packageObj.name, packageObj.directories.bin, exe),
                      path.join(nodeModules, ".bin", exe)
                  );
              }
              else {
                  console.log("skipping non-existent bin '" + exe + "'");
              }
          })
      }
    '';
  };

  prepareAndInvokeNPM = {packageName, bypassCache, reconstructLock, npmFlags, production}:
    let
      forceOfflineFlag = if bypassCache then "--offline" else "--registry http://www.example.com";
    in
    ''
        # Pinpoint the versions of all dependencies to the ones that are actually being used
        echo "pinpointing versions of dependencies..."
        source $pinpointDependenciesScriptPath

        # Patch the shebangs of the bundled modules to prevent them from
        # calling executables outside the Nix store as much as possible
        patchShebangs .

        # Deploy the Node.js package by running npm install. Since the
        # dependencies have been provided already by ourselves, it should not
        # attempt to install them again, which is good, because we want to make
        # it Nix's responsibility. If it needs to install any dependencies
        # anyway (e.g. because the dependency parameters are
        # incomplete/incorrect), it fails.
        #
        # The other responsibilities of NPM are kept -- version checks, build
        # steps, postprocessing etc.

        export HOME=$TMPDIR
        cd "${packageName}"
        runHook preRebuild

        ${lib.optionalString bypassCache ''
          ${lib.optionalString reconstructLock ''
            if [ -f package-lock.json ]
            then
                echo "WARNING: Reconstruct lock option enabled, but a lock file already exists!"
                echo "This will most likely result in version mismatches! We will remove the lock file and regenerate it!"
                rm package-lock.json
            else
                echo "No package-lock.json file found, reconstructing..."
            fi

            node ${reconstructPackageLock}
          ''}

          node ${addIntegrityFieldsScript}
        ''}

        npm ${forceOfflineFlag} --nodedir=${nodeSources} ${npmFlags} ${lib.optionalString production "--production"} rebuild

        runHook postRebuild

        if [ "''${dontNpmInstall-}" != "1" ]
        then
            # NPM tries to download packages even when they already exist if npm-shrinkwrap is used.
            rm -f npm-shrinkwrap.json

            npm ${forceOfflineFlag} --nodedir=${nodeSources} --no-bin-links --ignore-scripts ${npmFlags} ${lib.optionalString production "--production"} install
        fi

        # Link executables defined in package.json
        node ${linkBinsScript}
    '';

  # Builds and composes an NPM package including all its dependencies
  buildNodePackage =
    { name
    , packageName
    , version ? null
    , dependencies ? []
    , buildInputs ? []
    , production ? true
    , npmFlags ? ""
    , dontNpmInstall ? false
    , bypassCache ? false
    , reconstructLock ? false
    , preRebuild ? ""
    , dontStrip ? true
    , unpackPhase ? "true"
    , buildPhase ? "true"
    , meta ? {}
    , ... }@args:

    let
      extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "preRebuild" "unpackPhase" "buildPhase" "meta" ];
    in
    stdenv.mkDerivation ({
      name = "${name}${if version == null then "" else "-${version}"}";
      buildInputs = [ tarWrapper python nodejs ]
        ++ lib.optional (stdenv.isLinux) utillinux
        ++ lib.optional (stdenv.isDarwin) libtool
        ++ buildInputs;

      inherit nodejs;

      inherit dontStrip; # Stripping may fail a build for some package deployments
      inherit dontNpmInstall preRebuild unpackPhase buildPhase;

      compositionScript = composePackage args;
      pinpointDependenciesScript = pinpointDependenciesOfPackage args;

      passAsFile = [ "compositionScript" "pinpointDependenciesScript" ];

      installPhase = ''
        source ${installPackage}

        # Create and enter a root node_modules/ folder
        mkdir -p $out/lib/node_modules
        cd $out/lib/node_modules

        # Compose the package and all its dependencies
        source $compositionScriptPath

        ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}

        # Create symlink to the deployed executable folder, if applicable
        if [ -d "$out/lib/node_modules/.bin" ]
        then
            ln -s $out/lib/node_modules/.bin $out/bin

            # Patch the shebang lines of all the executables
            ls $out/bin/* | while read i
            do
                file="$(readlink -f "$i")"
                chmod u+rwx "$file"
                patchShebangs "$file"
            done
        fi

        # Create symlinks to the deployed manual page folders, if applicable
        if [ -d "$out/lib/node_modules/${packageName}/man" ]
        then
            mkdir -p $out/share
            for dir in "$out/lib/node_modules/${packageName}/man/"*
            do
                mkdir -p $out/share/man/$(basename "$dir")
                for page in "$dir"/*
                do
                    ln -s $page $out/share/man/$(basename "$dir")
                done
            done
        fi

        # Run post install hook, if provided
        runHook postInstall
      '';

      meta = {
        # default to Node.js' platforms
        platforms = nodejs.meta.platforms;
      } // meta;
    } // extraArgs);

  # Builds a node environment (a node_modules folder and a set of binaries)
  buildNodeDependencies =
    { name
    , packageName
    , version ? null
    , src
    , dependencies ? []
    , buildInputs ? []
    , production ? true
    , npmFlags ? ""
    , dontNpmInstall ? false
    , bypassCache ? false
    , reconstructLock ? false
    , dontStrip ? true
    , unpackPhase ? "true"
    , buildPhase ? "true"
    , ... }@args:

    let
      extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" ];
    in
      stdenv.mkDerivation ({
        name = "node-dependencies-${name}${if version == null then "" else "-${version}"}";

        buildInputs = [ tarWrapper python nodejs ]
          ++ lib.optional (stdenv.isLinux) utillinux
          ++ lib.optional (stdenv.isDarwin) libtool
          ++ buildInputs;

        inherit dontStrip; # Stripping may fail a build for some package deployments
        inherit dontNpmInstall unpackPhase buildPhase;

        includeScript = includeDependencies { inherit dependencies; };
        pinpointDependenciesScript = pinpointDependenciesOfPackage args;

        passAsFile = [ "includeScript" "pinpointDependenciesScript" ];

        installPhase = ''
          source ${installPackage}

          mkdir -p $out/${packageName}
          cd $out/${packageName}

          source $includeScriptPath

          # Create fake package.json to make the npm commands work properly
          cp ${src}/package.json .
          chmod 644 package.json
          ${lib.optionalString bypassCache ''
            if [ -f ${src}/package-lock.json ]
            then
                cp ${src}/package-lock.json .
                chmod 644 package-lock.json
            fi
          ''}

          # Go to the parent folder to make sure that all packages are pinpointed
          cd ..
          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}

          ${prepareAndInvokeNPM { inherit packageName bypassCache reconstructLock npmFlags production; }}

          # Expose the executables that were installed
          cd ..
          ${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}

          mv ${packageName} lib
          ln -s $out/lib/node_modules/.bin $out/bin
        '';
      } // extraArgs);

  # Builds a development shell
  buildNodeShell =
    { name
    , packageName
    , version ? null
    , src
    , dependencies ? []
    , buildInputs ? []
    , production ? true
    , npmFlags ? ""
    , dontNpmInstall ? false
    , bypassCache ? false
    , reconstructLock ? false
    , dontStrip ? true
    , unpackPhase ? "true"
    , buildPhase ? "true"
    , ... }@args:

    let
      nodeDependencies = buildNodeDependencies args;
      extraArgs = removeAttrs args [ "name" "dependencies" "buildInputs" "dontStrip" "dontNpmInstall" "unpackPhase" "buildPhase" ];
    in
    stdenv.mkDerivation ({
      name = "node-shell-${name}${if version == null then "" else "-${version}"}";

      buildInputs = [ python nodejs ] ++ lib.optional (stdenv.isLinux) utillinux ++ buildInputs;
      buildCommand = ''
        mkdir -p $out/bin
        cat > $out/bin/shell <<EOF
        #! ${stdenv.shell} -e
        $shellHook
        exec ${stdenv.shell}
        EOF
        chmod +x $out/bin/shell
      '';

      # Provide the dependencies in a development shell through the NODE_PATH environment variable
      inherit nodeDependencies;
      shellHook = lib.optionalString (dependencies != []) ''
        export NODE_PATH=${nodeDependencies}/lib/node_modules
        export PATH="${nodeDependencies}/bin:$PATH"
      '';
    } // extraArgs);
in
{
  buildNodeSourceDist = lib.makeOverridable buildNodeSourceDist;
  buildNodePackage = lib.makeOverridable buildNodePackage;
  buildNodeDependencies = lib.makeOverridable buildNodeDependencies;
  buildNodeShell = lib.makeOverridable buildNodeShell;
}
