{ lib, stdenv, fetchurl, dpkg, makeWrapper, patchelf
, coreutils, systemd, glib, zlib, xz, curl, libxml2
}:

let
  version = "5.1.17.3394";
  # libxml2's "out" output has lib/libxml2.so.16
  libxml2_out = libxml2.out;

  # System library RPATH for all bundled ELF binaries (cisco's own lib dir is
  # appended during fixupPhase via $out)
  sysRpath = lib.makeLibraryPath [
    systemd glib zlib xz stdenv.cc.cc.lib curl libxml2_out
  ];
in stdenv.mkDerivation {
  pname = "cisco-secure-client";
  inherit version;

  src = fetchurl {
    url = "https://archive.org/download/cisco-secure-client-linux64-${version}/cisco-secure-client-linux64-${version}-predeploy-deb-k9.tgz";
    sha256 = "5c4cafb4694e64cbf041481f5df3d70389399926f8aa2a469d480c0555b58c2c";
  };

  nativeBuildInputs = [ dpkg makeWrapper patchelf ];

  buildInputs = [
    systemd glib zlib xz stdenv.cc.cc.lib curl libxml2_out
  ];

  dontStrip = true;
  dontAutoPatchelf = true;

  unpackPhase = ''
    tar xzf "$src"
    DEB_FILE=$(ls cisco-secure-client-vpn-cli_*_amd64.deb 2>/dev/null || true)
    if [ -z "$DEB_FILE" ]; then
      DEB_FILE=$(ls cisco-secure-client-vpn_*_amd64.deb 2>/dev/null || true)
    fi
    if [ -z "$DEB_FILE" ]; then
      echo "ERROR: No .deb file found"
      exit 1
    fi
    dpkg-deb -x "$DEB_FILE" .
  '';

  installPhase = ''
    runHook preInstall
    mkdir -p "$out"
    cp -r opt/* "$out/"
    runHook postInstall
  '';

  # fixupPhase: patchelf corrupts Cisco's embedded code signatures on ALL
  # shipped ELF binaries and .so plugins. We skip patchelf entirely and
  # instead rely on LD_LIBRARY_PATH wrappers for system library resolution.
  # The binaries' original RPATH of /opt/cisco/secureclient/lib resolves
  # correctly at runtime via the /opt/cisco/secureclient -> store symlink.
  fixupPhase = ''
    runHook preFixup

    # Fix absolute symlinks — the deb assumes install under /opt/cisco/secureclient/
    # but nix puts it in the store. Convert to relative symlinks.
    for link in $(find "$out" -type l); do
      target=$(readlink "$link")
      if echo "$target" | grep -q "^/opt/"; then
        rel=$(basename "$target")
        ln -sf "$rel" "$link"
      fi
    done

    for f in "$out"/cisco/secureclient/bin/* "$out"/cisco/secureclient/lib/*.so*; do
      chmod +x "$f" 2>/dev/null || true
    done

    # Create libxml2.so.2 symlink (SONAME mismatch: Cisco wants .2, nixpkgs provides .16)
    libxml2_so=$(find ${libxml2_out}/lib -name "libxml2.so.16*" 2>/dev/null | head -1)
    if [ -n "$libxml2_so" ]; then
      ln -sf "$libxml2_so" "$out/cisco/secureclient/lib/libxml2.so.2"
    fi

    # NO patchelf on Cisco ELFs — their embedded code signatures are
    # verified at runtime (especially plugins loaded by vpnagentd).
    # All ELFs keep their original RPATH /opt/cisco/secureclient/lib
    # which resolves via the tmpfiles symlink.
    # System libs are provided via LD_LIBRARY_PATH in wrappers below.

    ldPath="$out/cisco/secureclient/lib:${sysRpath}"

    # Wrap vpn CLI — wrapProgram renames the original to .vpn-wrapped
    wrapProgram "$out/cisco/secureclient/bin/vpn" \
      --prefix LD_LIBRARY_PATH : "$ldPath" \
      --prefix PATH : ${lib.makeBinPath [ coreutils ]}

    # Create $out/bin/ wrappers for all user-facing executables
    mkdir -p "$out/bin"

    makeWrapper "$out/cisco/secureclient/bin/vpn" "$out/bin/vpn" \
      --prefix LD_LIBRARY_PATH : "$ldPath" \
      --prefix PATH : ${lib.makeBinPath [ coreutils ]}

    makeWrapper "$out/cisco/secureclient/bin/vpnagentd" "$out/bin/vpnagentd" \
      --prefix LD_LIBRARY_PATH : "$ldPath" \
      --prefix PATH : ${lib.makeBinPath [ coreutils ]}

    for cli in acinstallhelper manifesttool_vpn vpndownloader-cli; do
      if [ -f "$out/cisco/secureclient/bin/$cli" ]; then
        makeWrapper "$out/cisco/secureclient/bin/$cli" "$out/bin/$cli" \
          --prefix LD_LIBRARY_PATH : "$ldPath"
      fi
    done

    runHook postFixup
  '';

  meta = with lib; {
    description = "Cisco Secure Client (AnyConnect successor) VPN client";
    homepage = "https://www.cisco.com/site/us/en/products/security/secure-client/index.html";
    sourceProvenance = with sourceTypes; [ binaryNativeCode ];
    license = {
      name = "Cisco Secure Client EULA — proprietary, not redistributable";
      url = "https://www.cisco.com/c/en/us/products/security/secure-client/eula.html";
    };
    platforms = [ "x86_64-linux" ];
    maintainers = [ ];
  };
}
