import { createHash } from "node:crypto";

function sha256(value) {
  return createHash("sha256").update(value).digest("hex");
}

export const PYTHON_LEGAL_RESOURCES = Object.freeze([
  {
    component: "Pyodide",
    output: "LICENSE.pyodide.txt",
    url: "https://raw.githubusercontent.com/pyodide/pyodide/ac57031be7564f864d061cb37c5c152e59f83ad4/LICENSE",
    sourceSha256:
      "1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5",
    outputSha256:
      "1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5",
    transformation: "verbatim",
  },
  {
    component: "Pyodide vendored Error Stack Parser and StackFrame",
    output: "LICENSE.pyodide-stacktrace-vendors.txt",
    url: "https://raw.githubusercontent.com/stacktracejs/error-stack-parser/9f33c224b5d7b607755eb277f9d51fcdb7287e24/LICENSE",
    sourceSha256:
      "899da9d991cb211a3642b84e82a9ae0b4b4e44546fd207e34d7d4ec2eb40f420",
    outputSha256:
      "899da9d991cb211a3642b84e82a9ae0b4b4e44546fd207e34d7d4ec2eb40f420",
    transformation: "verbatim",
  },
  {
    component: "CPython",
    output: "LICENSE.cpython.txt",
    url: "https://raw.githubusercontent.com/python/cpython/df793163d5821791d4e7caf88885a2c11a107986/LICENSE",
    sourceSha256:
      "b0e25a78cffb43f4d92de8b61ccfa1f1f98ecbc22330b54b5251e7b6ba010231",
    outputSha256:
      "b0e25a78cffb43f4d92de8b61ccfa1f1f98ecbc22330b54b5251e7b6ba010231",
    transformation: "verbatim",
  },
  {
    component: "CPython bundled components",
    output: "NOTICE.cpython-bundled.rst",
    url: "https://raw.githubusercontent.com/python/cpython/df793163d5821791d4e7caf88885a2c11a107986/Doc/license.rst",
    sourceSha256:
      "c695d550b135e53e38807e76496d1db17d22c40e461d1f3f354c86188d3305dd",
    outputSha256:
      "c695d550b135e53e38807e76496d1db17d22c40e461d1f3f354c86188d3305dd",
    transformation: "verbatim",
  },
  {
    component: "Expat vendored by CPython",
    output: "LICENSE.expat.txt",
    url: "https://raw.githubusercontent.com/python/cpython/df793163d5821791d4e7caf88885a2c11a107986/Modules/expat/COPYING",
    sourceSha256:
      "122f2c27000472a201d337b9b31f7eb2b52d091b02857061a8880371612d9534",
    outputSha256:
      "122f2c27000472a201d337b9b31f7eb2b52d091b02857061a8880371612d9534",
    transformation: "verbatim",
  },
  {
    component: "libmpdec vendored by CPython",
    output: "LICENSE.libmpdec.txt",
    url: "https://raw.githubusercontent.com/python/cpython/df793163d5821791d4e7caf88885a2c11a107986/Modules/_decimal/libmpdec/mpdecimal.c",
    sourceSha256:
      "4f89b8095e408a18deff79cfb605299e615bae747898eb105d8936064f7fb626",
    outputSha256:
      "b07528d8b1dbf1e2d2741052996f0876e23342ce2d30d0effa39c5457716c25a",
    transformation: "leading-c-comment",
  },
  {
    component: "HACL* vendored by CPython",
    output: "LICENSE.hacl-mit.txt",
    url: "https://raw.githubusercontent.com/python/cpython/df793163d5821791d4e7caf88885a2c11a107986/Modules/_hacl/Hacl_HMAC.c",
    sourceSha256:
      "142adb769ff02b8a5327f0eb837e1f9a797bdf9a1684d21acd749dbb5b2e5be2",
    outputSha256:
      "998ce04fb8ad9dedb0bc1b44938f8c3dcf1089780fa105ce1c8c30fb5554d78c",
    transformation: "leading-c-comment",
  },
  {
    component: "libffi",
    output: "LICENSE.libffi.txt",
    url: "https://raw.githubusercontent.com/libffi/libffi/f08493d249d2067c8b3207ba46693dd858f95db3/LICENSE",
    sourceSha256:
      "2c9c2acb9743e6b007b91350475308aee44691d96aa20eacef8e199988c8c388",
    outputSha256:
      "2c9c2acb9743e6b007b91350475308aee44691d96aa20eacef8e199988c8c388",
    transformation: "verbatim",
  },
  {
    component: "Hiwire",
    output: "LICENSE.hiwire.txt",
    url: "https://raw.githubusercontent.com/pyodide/hiwire/6a1e67280a15d929ebeceee54a6358c9c8d5f697/LICENSE",
    sourceSha256:
      "1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5",
    outputSha256:
      "1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5",
    transformation: "verbatim",
  },
  {
    component: "XZ Utils liblzma",
    output: "LICENSE.xz.txt",
    url: "https://raw.githubusercontent.com/xz-mirror/xz/9815cdf6987ef91a85493bfcfd1ce2aaf3b47a0a/COPYING",
    sourceSha256:
      "c4f8e14fafe458d84808a4cd8b69f94673ebe2bf8fc992291629a69ac12218f8",
    outputSha256:
      "c4f8e14fafe458d84808a4cd8b69f94673ebe2bf8fc992291629a69ac12218f8",
    transformation: "verbatim",
  },
  {
    component: "Zstandard",
    output: "LICENSE.zstd.txt",
    url: "https://raw.githubusercontent.com/python/cpython-source-deps/eef946ae8cf1591c0e5cc5f43486210768647c2e/LICENSE",
    sourceSha256:
      "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8",
    outputSha256:
      "7055266497633c9025b777c78eb7235af13922117480ed5c674677adc381c9d8",
    transformation: "verbatim",
  },
  {
    component: "SQLite",
    output: "LICENSE.sqlite.txt",
    url: "https://raw.githubusercontent.com/sqlite/sqlite/47d8c40ca522babfadf3f774d9869cf5f6a5896e/LICENSE.md",
    sourceSha256:
      "9c6479123f32a1ed50d9a0af203dfe8972e65035b0cdeef436b5f8d0924517fe",
    outputSha256:
      "9c6479123f32a1ed50d9a0af203dfe8972e65035b0cdeef436b5f8d0924517fe",
    transformation: "verbatim",
  },
  {
    component: "bzip2",
    output: "LICENSE.bzip2.txt",
    url: "https://raw.githubusercontent.com/emscripten-ports/bzip2/60ce9dfe9a75f7ee92956aba8a83d1a37625bc1d/LICENSE",
    sourceSha256:
      "4919cfb14a73cd64fcef67b107613970cf1659a09aa675dba31314f373bc7204",
    outputSha256:
      "4919cfb14a73cd64fcef67b107613970cf1659a09aa675dba31314f373bc7204",
    transformation: "verbatim",
  },
  {
    component: "zlib",
    output: "LICENSE.zlib.txt",
    url: "https://raw.githubusercontent.com/madler/zlib/51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf/LICENSE",
    sourceSha256:
      "845efc77857d485d91fb3e0b884aaa929368c717ae8186b66fe1ed2495753243",
    outputSha256:
      "845efc77857d485d91fb3e0b884aaa929368c717ae8186b66fe1ed2495753243",
    transformation: "verbatim",
  },
  {
    component: "Emscripten",
    output: "LICENSE.emscripten.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/LICENSE",
    sourceSha256:
      "620a78084fc7ca97c0b5dea9abf891f3ffcadfdbf305276f099c9c4e12fc1d86",
    outputSha256:
      "620a78084fc7ca97c0b5dea9abf891f3ffcadfdbf305276f099c9c4e12fc1d86",
    transformation: "verbatim",
  },
  {
    component: "dlmalloc in Emscripten",
    output: "NOTICE.emscripten-dlmalloc.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/dlmalloc.c",
    sourceSha256:
      "c008dc3c2b005ba822efb1bf6187a9d7a6aecd096826c6f28c6f5ee62885053d",
    outputSha256:
      "3a146a183961471088fac25b17b1e5e0b4b400439ae3abcf2fcd5a9b2a2f582c",
    transformation: "dlmalloc-public-domain-header",
  },
  {
    component: "musl libc in Emscripten",
    output: "NOTICE.emscripten-musl.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/libc/musl/COPYRIGHT",
    sourceSha256:
      "f9bc4423732350eb0b3f7ed7e91d530298476f8fec0c6c427a1c04ade22655af",
    outputSha256:
      "f9bc4423732350eb0b3f7ed7e91d530298476f8fec0c6c427a1c04ade22655af",
    transformation: "verbatim",
  },
  {
    component: "LLVM compiler-rt in Emscripten",
    output: "LICENSE.llvm-compiler-rt.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/compiler-rt/LICENSE.TXT",
    sourceSha256:
      "1a8f1058753f1ba890de984e48f0242a3a5c29a6a8f2ed9fd813f36985387e8d",
    outputSha256:
      "1a8f1058753f1ba890de984e48f0242a3a5c29a6a8f2ed9fd813f36985387e8d",
    transformation: "verbatim",
  },
  {
    component: "LLVM libc++ in Emscripten",
    output: "LICENSE.llvm-libcxx.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/libcxx/LICENSE.TXT",
    sourceSha256:
      "539dd7aed86e8a4f12cbdd0e6c50c189c7d74847e4fecc64ce2c6ee3a01da38b",
    outputSha256:
      "539dd7aed86e8a4f12cbdd0e6c50c189c7d74847e4fecc64ce2c6ee3a01da38b",
    transformation: "verbatim",
  },
  {
    component: "LLVM libc++abi in Emscripten",
    output: "LICENSE.llvm-libcxxabi.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/libcxxabi/LICENSE.TXT",
    sourceSha256:
      "e2b35be49f7284a45b7baca8fc7b3ab7440e7902392b2528a457816b5bb2a15c",
    outputSha256:
      "e2b35be49f7284a45b7baca8fc7b3ab7440e7902392b2528a457816b5bb2a15c",
    transformation: "verbatim",
  },
  {
    component: "LLVM libunwind in Emscripten",
    output: "LICENSE.llvm-libunwind.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/system/lib/libunwind/LICENSE.TXT",
    sourceSha256:
      "b5efebcaca80879234098e52d1725e6d9eb8fb96a19fce625d39184b705f7b6d",
    outputSha256:
      "b5efebcaca80879234098e52d1725e6d9eb8fb96a19fce625d39184b705f7b6d",
    transformation: "verbatim",
  },
  {
    component: "MiniLZ4 in Emscripten",
    output: "LICENSE.emscripten-mini-lz4.txt",
    url: "https://raw.githubusercontent.com/emscripten-core/emscripten/285c424dfa9e83b03cf8490c65ceadb7c45f28eb/third_party/mini-lz4.js",
    sourceSha256:
      "ac1eaa04b68d792d962d5946504ee5141ef58a9df86a0dfcf0ffa63d08634e46",
    outputSha256:
      "d27097e98c94f60e7f96e31e90296f32789738c1f8f271df785fe1dda9d52baa",
    transformation: "leading-c-comment",
  },
]);

const CPYTHON_PATCHES = Object.freeze(
  [
    [
      "cpython/patches/0001-Public-pymain_run_python.patch",
      "ad29aa6d748176b873846bf14d601b65a694d002743792ae226d737c8bf67d5d",
    ],
    [
      "cpython/patches/0002-Fix-LONG_BIT-constant-to-be-always-32bit.patch",
      "e840dcb6c2f70ce7e2029ff51028fc980f0f98f6807c755a63ba1336c791ce08",
    ],
    [
      "cpython/patches/0003-Add-call-to-JsProxy_GetMethod-to-help-remove-tempora.patch",
      "a359c12516cc2f08720096d51f8cfb31d62ce57d096255beae0ca6848ede8cbe",
    ],
    [
      "cpython/patches/0004-Make-from-x-import-aware-of-jsproxy-modules.patch",
      "4297a7694d0f58e5c620f322b94bfdeef6ef5926bdf62d7dd9038c80d4f51720",
    ],
    [
      "cpython/patches/0005-Remove-JSPI-related-parts-in-emscripten_syscalls.c.patch",
      "5f7a57b74af22f3d2afd89d0cb99b8a44eed37d2b7a7cbbc28fe8f796c99d5cb",
    ],
    [
      "cpython/patches/0006-Teach-json-encoder.py-to-encode-jsnull.patch",
      "ba13244a5c1003f55c4ddfb4087c977c38b5fdeccf68f819deb0617bf04adc6a",
    ],
    [
      "cpython/patches/0007-Warn-if-ZoneInfo-is-imported-without-tzdata.patch",
      "bcf92273acce4b4b0ea8bed3fab3f375e944a2874a27b0f8e7b79ecb40f5a685",
    ],
    [
      "cpython/patches/0008-Export-_Py_emscripten_signal_clock-and-_Py_emscripte.patch",
      "7cf220d962a8a1f24d7c96a588d9c1f3d32849c3bc89329cbf76dff517ca737b",
    ],
    [
      "cpython/patches/0009-Fix-Emscripten-trampoline-with-emcc-4.0.19.patch",
      "e4de0006020fa3118da139e566a6eea3d747ef11d39785d1d7cc5e74c8638371",
    ],
  ].map(([path, digest]) => ({ path, sha256: digest })),
);

const EMSCRIPTEN_PATCHES = Object.freeze(
  [
    [
      "emsdk/patches/0001-Add-useful-error-when-symbol-resolution-fails.patch",
      "49fe15971dffd37da96ecaa55de036890c92d06a752d9bc481299ef844f22ab7",
    ],
    [
      "emsdk/patches/0002-Fix-promise-order.patch",
      "7e6166923dc703fb571b449334ebcfbebfc5283c322d740297bf213a3e508089",
    ],
    [
      "emsdk/patches/0003-dylink-Normalize-library-paths-to-prevent-duplicate-loading.patch",
      "6b04b74f6737f0e604a524e4217c7d5859a852e57308fce3793c7e07f64b33a0",
    ],
    [
      "emsdk/patches/0004-Append-pic-directory-when-SIDE_MODULE.patch",
      "4e96b6bff08733dab7cad4f52e368df3669e518e0cf3aa8ba297e8097fb22147",
    ],
    [
      "emsdk/patches/0005-Don-t-bundle-the-LLVM-profile-runtime-into-libcompil.patch",
      "cf23a6cb9a8b0c83230564f171afc559110dae4c4d6afa572c700264741244d8",
    ],
  ].map(([path, digest]) => ({ path, sha256: digest })),
);

const SOURCE_INPUTS = Object.freeze([
  {
    id: "pyodide",
    version: "314.0.3",
    kind: "git",
    repository: "https://github.com/pyodide/pyodide.git",
    tag: "314.0.3",
    commitSha1: "ac57031be7564f864d061cb37c5c152e59f83ad4",
    treeSha1: "42da435a964851c39c7709bc06ef860fea80216a",
    license: "MPL-2.0",
  },
  {
    id: "pyodide-build",
    kind: "git-submodule",
    repository: "https://github.com/pyodide/pyodide-build.git",
    commitSha1: "03e7e6340d5b6eb5ef66430e391d8c2e821870df",
    treeSha1: "00d37c9eed9a479fd06bda67cedb367ec7249df9",
    pathInPyodide: "pyodide-build",
    license: "MPL-2.0",
  },
  {
    id: "error-stack-parser",
    version: "2.1.4",
    kind: "npm-source-archive-and-git",
    repository: "https://github.com/stacktracejs/error-stack-parser.git",
    tag: "v2.1.4",
    tagObjectSha1: "ce4d80da15c9124619cb086a7c26dbc3d71abf37",
    commitSha1: "9f33c224b5d7b607755eb277f9d51fcdb7287e24",
    treeSha1: "117482015c5aadf01fe2ed85e6ac78fabf6538e0",
    archive: {
      url: "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
      sha256:
        "e346f48f4fc606d4e52bf75806e439225508d914d147eb741df3076769ac2385",
      integrity:
        "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
    },
    vendoredPort: {
      pyodideIntroductionCommitSha1: "b46e4a572d16dd96eb29b49f87fd8d34c2bc9c2e",
      path: "src/js/vendor/stackframe/error-stack-parser.ts",
      sha256:
        "06cb52d1e4ae6a0f9c3f349ba4751b1839dfe7a3515f74373f0a7fab62c52b8d",
      versionEvidence: {
        packageLockCommitSha1: "8b3e7c4cf25ed9fd0a983ba33cdf0afc36b77647",
        packageLockPath: "src/js/package-lock.json",
        packageLockSha256:
          "34cc94816d3cfdffe858e9c1f85c876f470fd886bd2de1063dd5d82199d84268",
      },
    },
    license: "MIT",
  },
  {
    id: "stackframe",
    version: "1.3.4",
    kind: "npm-source-archive-and-git",
    repository: "https://github.com/stacktracejs/stackframe.git",
    tag: "v1.3.4",
    tagObjectSha1: "6b68182ca814c4994c705fb561c9689dd5484998",
    commitSha1: "e07cfd43e89b0565f41856e9285d154aee6c0be3",
    treeSha1: "bc5fd9aa47c649bd8cf0bc53d69993e51c4f106c",
    archive: {
      url: "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
      sha256:
        "fb928460cb97df0ba99a1dfbeec6cb1dc9b12f9a9838a003fda25019ad9be929",
      integrity:
        "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
    },
    vendoredPort: {
      pyodideIntroductionCommitSha1: "b46e4a572d16dd96eb29b49f87fd8d34c2bc9c2e",
      path: "src/js/vendor/stackframe/stackframe.ts",
      sha256:
        "f1ac1bce24f9a936957975f6205cf49337c46f6b32591e807f168ca377b392a4",
      versionEvidence: {
        packageLockCommitSha1: "8b3e7c4cf25ed9fd0a983ba33cdf0afc36b77647",
        packageLockPath: "src/js/package-lock.json",
        packageLockSha256:
          "34cc94816d3cfdffe858e9c1f85c876f470fd886bd2de1063dd5d82199d84268",
      },
    },
    license: "MIT",
  },
  {
    id: "cpython",
    version: "3.14.2",
    kind: "release-archive-and-git",
    repository: "https://github.com/python/cpython.git",
    tag: "v3.14.2",
    tagObjectSha1: "a1d0069daf8e85b25a0c3f96abc43182be6d429e",
    commitSha1: "df793163d5821791d4e7caf88885a2c11a107986",
    treeSha1: "0110cee4f97a291ec6381838aac55e8183115ec5",
    archive: {
      url: "https://www.python.org/ftp/python/3.14.2/Python-3.14.2.tgz",
      sha256:
        "c609e078adab90e2c6bacb6afafacd5eaf60cd94cf670f1e159565725fcd448d",
    },
    license: "Python-2.0",
  },
  {
    id: "libffi",
    kind: "git",
    repository: "https://github.com/libffi/libffi.git",
    commitSha1: "f08493d249d2067c8b3207ba46693dd858f95db3",
    treeSha1: "fcacfbb6e4f0e3cb557f7dd733816c859c13588b",
    license: "MIT",
  },
  {
    id: "hiwire",
    version: "1.0.1",
    kind: "git",
    repository: "https://github.com/pyodide/hiwire.git",
    tag: "1.0.1",
    tagObjectSha1: "b0e3754248b05c22ab40360bcecc4c35425eac4c",
    commitSha1: "6a1e67280a15d929ebeceee54a6358c9c8d5f697",
    treeSha1: "7cd355c4e33f447004c13eeaed9a1bcbd30175f6",
    license: "MPL-2.0",
  },
  {
    id: "xz-liblzma",
    version: "5.2.2",
    kind: "release-archive-and-git",
    repository: "https://github.com/xz-mirror/xz.git",
    tag: "v5.2.2",
    tagObjectSha1: "33e803345765854e065bfd58c72ea30ed7f75173",
    commitSha1: "9815cdf6987ef91a85493bfcfd1ce2aaf3b47a0a",
    treeSha1: "20acf559acea1c2fca2fd80e7edc85587ea712f9",
    archive: {
      url: "https://github.com/xz-mirror/xz/releases/download/v5.2.2/xz-5.2.2.tar.gz",
      sha256:
        "73df4d5d34f0468bd57d09f2d8af363e95ed6cc3a4a86129d2f2c366259902a2",
    },
    license: "LicenseRef-XZ-Public-Domain-With-Fallback-Grant",
  },
  {
    id: "zstandard",
    version: "1.5.7",
    kind: "release-archive-and-git",
    repository: "https://github.com/python/cpython-source-deps.git",
    tag: "zstd-1.5.7",
    commitSha1: "eef946ae8cf1591c0e5cc5f43486210768647c2e",
    treeSha1: "65df13bfb803791fd5d2073f3ce86a8743dd05ff",
    archive: {
      url: "https://github.com/python/cpython-source-deps/archive/refs/tags/zstd-1.5.7.tar.gz",
      sha256:
        "f24b52470d12f466e9fa4fcc94e6c530625ada51d7b36de7fdc6ed7e6f499c8e",
    },
    license: "BSD-3-Clause",
  },
  {
    id: "sqlite",
    version: "3.39.0",
    kind: "release-archive-and-git",
    repository: "https://github.com/sqlite/sqlite.git",
    tag: "version-3.39.0",
    commitSha1: "47d8c40ca522babfadf3f774d9869cf5f6a5896e",
    treeSha1: "23f10739e181800d49540f2836478e543862d971",
    archive: {
      url: "https://www.sqlite.org/2022/sqlite-autoconf-3390000.tar.gz",
      sha256:
        "e90bcaef6dd5813fcdee4e867f6b65f3c9bfd0aec0f1017f9f3bbce1e4ed09e2",
    },
    license: "LicenseRef-SQLite-Public-Domain-Blessing",
  },
  {
    id: "bzip2",
    version: "1.0.6",
    kind: "release-archive-and-git",
    repository: "https://github.com/emscripten-ports/bzip2.git",
    tag: "1.0.6",
    commitSha1: "60ce9dfe9a75f7ee92956aba8a83d1a37625bc1d",
    treeSha1: "d5950f6fa509172a4195f8e7536ee404f0f09af4",
    archive: {
      url: "https://github.com/emscripten-ports/bzip2/archive/1.0.6.zip",
      sha256:
        "9628e7bc598719335ce1d1219c1a4fc241652c0a7b4d993fa82a9b98a6c5dec6",
      upstreamSha512:
        "512cbfde5144067f677496452f3335e9368fd5d7564899cb49e77847b9ae7dca598218276637cbf5ec524523be1e8ace4ad36a148ef7f4badf3f6d5a002a4bb2",
    },
    license: "bzip2-1.0.6",
  },
  {
    id: "zlib",
    version: "1.3.1",
    kind: "release-archive-and-git",
    repository: "https://github.com/madler/zlib.git",
    tag: "v1.3.1",
    tagObjectSha1: "925af44f3cde53c6b076611c297850091b5dc7bb",
    commitSha1: "51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf",
    treeSha1: "16b86ef85c591c244523c98c71508be7908d1189",
    archive: {
      url: "https://github.com/madler/zlib/archive/refs/tags/v1.3.1.tar.gz",
      sha256:
        "17e88863f3600672ab49182f217281b6fc4d3c762bde361935e436a95214d05c",
      upstreamSha512:
        "8c9642495bafd6fad4ab9fb67f09b268c69ff9af0f4f20cf15dfc18852ff1f312bd8ca41de761b3f8d8e90e77d79f2ccacd3d4c5b19e475ecf09d021fdfe9088",
    },
    license: "Zlib",
  },
  {
    id: "emscripten",
    version: "5.0.3",
    kind: "git",
    repository: "https://github.com/emscripten-core/emscripten.git",
    tag: "5.0.3",
    commitSha1: "285c424dfa9e83b03cf8490c65ceadb7c45f28eb",
    treeSha1: "390d84c64eb93ae47aa9d71cf1cd2f74bc7c2b9e",
    license: "MIT OR NCSA",
  },
  {
    id: "hacl-star-preferred-source",
    kind: "git",
    repository: "https://github.com/hacl-star/hacl-star.git",
    commitSha1: "8ba599b2f6c9701b3dc961db895b0856a2210f76",
    treeSha1: "8efcb9246e0bf2593dca9fbfd94a34f7cee50fda",
    vendoredGeneratedSource:
      "CPython Modules/_hacl; CPython's refresh.sh pins this revision and records its deterministic copy/namespace transformations.",
    license: "MIT for the linked generated C sources",
  },
]);

const LINKED_COMPONENTS = Object.freeze([
  {
    id: "pyodide",
    version: "314.0.3",
    license: "MPL-2.0",
    noticeFiles: ["LICENSE.pyodide.txt"],
    evidence: "npm package identity plus the Pyodide loader and core module",
  },
  {
    id: "error-stack-parser",
    version: "2.1.4 vendored ES-module port",
    license: "MIT",
    noticeFiles: ["LICENSE.pyodide-stacktrace-vendors.txt"],
    evidence:
      "Pyodide compat.ts imports the vendored port; its source hash, introduction commit and exact upstream tag/archive are recorded here",
  },
  {
    id: "stackframe",
    version: "1.3.4 vendored ES-module port",
    license: "MIT",
    noticeFiles: ["LICENSE.pyodide-stacktrace-vendors.txt"],
    evidence:
      "The vendored Error Stack Parser imports the StackFrame port; its source hash, introduction commit and exact upstream tag/archive are recorded here",
  },
  {
    id: "cpython",
    version: "3.14.2",
    license: "Python-2.0 and bundled component terms",
    noticeFiles: ["LICENSE.cpython.txt", "NOTICE.cpython-bundled.rst"],
    evidence: "runtime sys.version and pinned Pyodide CPython recipe",
  },
  {
    id: "expat",
    version: "2.7.3",
    license: "MIT",
    noticeFiles: ["LICENSE.expat.txt"],
    evidence:
      "CPython vendored source and Pyodide LIBEXPAT_OBJS; executable contains expat_2.7.3",
  },
  {
    id: "libmpdec",
    version: "2.5.1",
    license: "BSD-2-Clause",
    noticeFiles: ["LICENSE.libmpdec.txt"],
    evidence:
      "CPython vendored source and Pyodide LIBMPDEC_OBJS; executable contains 2.5.1",
  },
  {
    id: "hacl-star",
    version: "commit 8ba599b2f6c9701b3dc961db895b0856a2210f76",
    license: "MIT for the linked generated C sources",
    noticeFiles: ["LICENSE.hacl-mit.txt"],
    evidence:
      "CPython _hmac static module and Modules/_hacl/refresh.sh preferred-source pin",
  },
  {
    id: "libffi",
    version: "commit f08493d249d2067c8b3207ba46693dd858f95db3",
    license: "MIT",
    noticeFiles: ["LICENSE.libffi.txt"],
    evidence: "Pyodide CPython Makefile pin and linked _ctypes/libffi symbols",
  },
  {
    id: "hiwire",
    version: "1.0.1",
    license: "MPL-2.0",
    noticeFiles: ["LICENSE.hiwire.txt"],
    evidence: "Pyodide CPython Makefile pin and linked hiwire symbols",
  },
  {
    id: "xz-liblzma",
    version: "5.2.2",
    license: "public domain with the upstream fallback permission grant",
    noticeFiles: ["LICENSE.xz.txt"],
    evidence:
      "Pyodide CPython Makefile archive pin and executable 5.2.2 string",
  },
  {
    id: "zstandard",
    version: "1.5.7",
    license: "BSD-3-Clause",
    noticeFiles: ["LICENSE.zstd.txt"],
    evidence:
      "Pyodide CPython Makefile archive pin and executable 1.5.7 string",
  },
  {
    id: "sqlite",
    version: "3.39.0",
    license: "public-domain dedication/blessing",
    noticeFiles: ["LICENSE.sqlite.txt"],
    evidence:
      "Pyodide CPython Makefile archive pin and executable 3.39.0 string",
  },
  {
    id: "bzip2",
    version: "1.0.6",
    license: "bzip2-1.0.6",
    noticeFiles: ["LICENSE.bzip2.txt"],
    evidence:
      "Pyodide -sUSE_BZIP2 and Emscripten 5.0.3 port lock; executable version string",
  },
  {
    id: "zlib",
    version: "1.3.1",
    license: "Zlib",
    noticeFiles: ["LICENSE.zlib.txt"],
    evidence:
      "Pyodide -sUSE_ZLIB and Emscripten 5.0.3 port lock; executable version string",
  },
  {
    id: "emscripten",
    version: "5.0.3 with the five Pyodide patches recorded here",
    license: "MIT OR NCSA",
    noticeFiles: ["LICENSE.emscripten.txt"],
    evidence: "Pyodide lock platform and build recipe",
  },
  {
    id: "emscripten-musl",
    version: "snapshot in Emscripten 5.0.3",
    license: "MIT plus file-level permissive terms",
    noticeFiles: ["NOTICE.emscripten-musl.txt"],
    evidence: "Emscripten system libc selected by the main-module link",
  },
  {
    id: "emscripten-llvm-runtime",
    version: "snapshot in Emscripten 5.0.3",
    license: "Apache-2.0 WITH LLVM-exception",
    noticeFiles: [
      "LICENSE.llvm-compiler-rt.txt",
      "LICENSE.llvm-libcxx.txt",
      "LICENSE.llvm-libcxxabi.txt",
      "LICENSE.llvm-libunwind.txt",
    ],
    evidence:
      "Conservative notice closure for compiler-rt, libc++, libc++abi and libunwind selected by the pinned Emscripten link; the stripped npm module retains no link map",
  },
  {
    id: "emscripten-dlmalloc",
    version: "2.8.6 snapshot in Emscripten 5.0.3",
    license: "public domain dedication",
    noticeFiles: ["NOTICE.emscripten-dlmalloc.txt"],
    evidence:
      "Emscripten 5.0.3 default MALLOC setting and independently hashed dlmalloc source dedication",
  },
  {
    id: "emscripten-mini-lz4",
    version: "snapshot in Emscripten 5.0.3",
    license: "MIT",
    noticeFiles: ["LICENSE.emscripten-mini-lz4.txt"],
    evidence:
      "Pyodide -sLZ4=1; executable loader contains MiniLZ4 after minification removed its source comment",
  },
]);

export const PYTHON_SOURCE_MANIFEST_BASE = Object.freeze({
  schemaVersion: 1,
  pack: "python",
  distribution: {
    npmPackage: "pyodide@314.0.3",
    resolved: "https://registry.npmjs.org/pyodide/-/pyodide-314.0.3.tgz",
    integrity:
      "sha512-sK40My6m8tmBUYtYH9au9rXUeh9x0wfahtHdOlGmJxZDsKBGKtP6KznyFB2+u/klbQTdDionR0uaVd176zVQzQ==",
    role: "Exact binary distribution input; no wheel named by pyodide-lock.json is bundled unless it is one of the separately enumerated base-runtime files.",
  },
  sourceAvailability: {
    preferredFormRoot:
      "https://github.com/pyodide/pyodide/tree/ac57031be7564f864d061cb37c5c152e59f83ad4",
    instructions: [
      "Clone the Pyodide repository, checkout commit ac57031be7564f864d061cb37c5c152e59f83ad4, verify tree 42da435a964851c39c7709bc06ef860fea80216a, and initialise the recorded pyodide-build submodule.",
      "Acquire each release archive below from its primary upstream URL and verify SHA-256 before extraction; Git inputs must match both commit and tree identities.",
      "Apply the CPython and Emscripten patch series in the listed lexical order. The patches and recipe files live in the exact Pyodide preferred-form source tree and are independently hashed below.",
      "Follow the pinned Pyodide Makefiles. The npm runtime is the exact distributed executable reference; this source route closes preferred-form and patch availability but does not claim a byte-identical rebuild across host SDK packaging changes.",
    ],
    regexToolsModification:
      "Regex Tools removes only the final //# sourceMappingURL=pyodide.mjs.map trailer from the copied loader; no executable statement in the upstream loader or WebAssembly module is changed.",
  },
  sourceInputs: SOURCE_INPUTS,
  buildRecipeFiles: [
    {
      path: "Makefile",
      sha256:
        "a00cd2fe502ee227a2fd53029cb51d833e043b260679544eabab5f96fc135719",
    },
    {
      path: "Makefile.envs",
      sha256:
        "091d32a55cef89e22d984eca596d23bcb711eefafa2aba5c7ae62079c1d634f8",
    },
    {
      path: "cpython/Makefile",
      sha256:
        "fbeeebe3363fa9da54b6908c903a16bbf736af65647a9fbfe277c8e40eb785bf",
    },
    {
      path: "cpython/Setup.local",
      sha256:
        "7fbbb0efe5497765122230c24ebc95861973bb985116f89705b6ff51cfcffa4c",
    },
    {
      path: "emsdk/Makefile",
      sha256:
        "8b2dfe4111c8ba746ecd475b6ee4774776ec090dc255c147ec56146b06a03fc8",
    },
  ],
  patches: {
    cpython: CPYTHON_PATCHES,
    emscripten: EMSCRIPTEN_PATCHES,
  },
  linkedComponents: LINKED_COMPONENTS,
});

export function transformPythonLegalResource(resource, source) {
  const actualSource = sha256(source);
  if (actualSource !== resource.sourceSha256) {
    throw new Error(
      `${resource.component} legal source SHA-256 mismatch: expected ${resource.sourceSha256}, got ${actualSource}.`,
    );
  }
  let output;
  if (resource.transformation === "verbatim") {
    output = source;
  } else if (resource.transformation === "leading-c-comment") {
    const match = /^\/\*[\s\S]*?\*\/\r?\n/u.exec(source.toString("utf8"));
    if (!match) {
      throw new Error(
        `${resource.component} legal source has no leading C comment.`,
      );
    }
    output = Buffer.from(match[0].replaceAll("\r\n", "\n"), "utf8");
  } else if (resource.transformation === "dlmalloc-public-domain-header") {
    const match =
      / This is a version \(aka dlmalloc\)[\s\S]*? Check before installing!\r?\n/u.exec(
        source.toString("utf8"),
      );
    if (!match) {
      throw new Error(
        `${resource.component} source has no pinned public-domain/version header.`,
      );
    }
    output = Buffer.from(match[0].replaceAll("\r\n", "\n").trimStart(), "utf8");
  } else {
    throw new Error(
      `${resource.component} has an unsupported legal transformation.`,
    );
  }
  const actualOutput = sha256(output);
  if (actualOutput !== resource.outputSha256) {
    throw new Error(
      `${resource.component} legal output SHA-256 mismatch: expected ${resource.outputSha256}, got ${actualOutput}.`,
    );
  }
  return output;
}

export function createPythonSourceManifest(legalFileRecords) {
  const expectedPaths = PYTHON_LEGAL_RESOURCES.map(({ output }) => output);
  if (
    legalFileRecords.length !== expectedPaths.length ||
    legalFileRecords.some(
      ({ path, sha256: digest }, index) =>
        path !== expectedPaths[index] ||
        digest !== PYTHON_LEGAL_RESOURCES[index].outputSha256,
    )
  ) {
    throw new Error(
      "Python legal file records do not match the pinned provenance inventory.",
    );
  }
  return {
    ...PYTHON_SOURCE_MANIFEST_BASE,
    legalFiles: legalFileRecords.map((record, index) => ({
      ...record,
      component: PYTHON_LEGAL_RESOURCES[index].component,
      sourceUrl: PYTHON_LEGAL_RESOURCES[index].url,
      sourceSha256: PYTHON_LEGAL_RESOURCES[index].sourceSha256,
      transformation: PYTHON_LEGAL_RESOURCES[index].transformation,
    })),
  };
}
