#!/usr/bin/env nix-shell
#!nix-shell -i bash -p git nix jq coreutils gnugrep gnused curl common-updater-scripts
# shellcheck shell=bash
set -euo pipefail

nixpkgs="$(git rev-parse --show-toplevel || (printf 'Could not find root of nixpkgs repo\nAre we running from within the nixpkgs git repo?\n' >&2; exit 1))"

stripwhitespace() {
    sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}

narhash() {
    nix --extra-experimental-features nix-command store prefetch-file --json "$1" | jq -r .hash
}

nixeval() {
    nix --extra-experimental-features nix-command eval --json --impure -f "$nixpkgs" "$1" | jq -r .
}

vendorhash() {
    (nix --extra-experimental-features nix-command build --no-link -f "$nixpkgs" --no-link "$1" 2>&1 >/dev/null | tail -n3 | grep -F got: | cut -d: -f2- | stripwhitespace) 2>/dev/null || true
}

findpath() {
    path="$(nix --extra-experimental-features nix-command eval --json --impure -f "$nixpkgs" "$1.meta.position" | jq -r . | cut -d: -f1)"
    outpath="$(nix --extra-experimental-features nix-command eval --json --impure --expr "fetchGit \"$nixpkgs\"")"

    if [ -n "$outpath" ]; then
        path="${path/$(echo "$outpath" | jq -r .)/$nixpkgs}"
    fi

    echo "$path"
}

getvar() {
    echo "$2" | grep -F "$1 " | sed -e 's/:=/:/g' | cut -d: -f2- | stripwhitespace
}

evalvar() {
    local out="$(getvar "$1" "$2")"

    # Replace $(VAR) within variables with other variables
    while [[ "$out" =~ (\$\(([A-Za-z_][A-Za-z0-9_]*)\)) ]]; do
        local match="${BASH_REMATCH[1]}"
        local var="${BASH_REMATCH[2]}"
        local value="$(getvar "$var" "$2")"
        out="${out//$match/$value}"
    done

    echo $out
}

attr="${UPDATE_NIX_ATTR_PATH:-curl-impersonate}"
version="$(curl -sSL "https://api.github.com/repos/lexiforest/curl-impersonate/releases/latest" | jq -r .tag_name | sed -e 's/^v//')"

pkgpath="$(findpath "$attr")"

updated="$(cd "$nixpkgs" && update-source-version "$attr" "$version" --file="$pkgpath" --print-changes | jq -r length)"

if [ "$updated" -eq 0 ]; then
    echo 'update.sh: Package version not updated, nothing to do.'
    exit 0
fi

vars="$(curl -sSL "https://github.com/lexiforest/curl-impersonate/raw/v$version/Makefile.in" | grep '^ *[^ ]*_\(VERSION\|URL\|COMMIT\) *:=')"

# TODO: Fix hash for curl.
cat >"$(dirname "$pkgpath")"/deps.nix <<EOF
# Generated by update.sh
{ fetchurl }:

{
  "$(getvar CURL_VERSION "$vars").tar.gz" = fetchurl {
    url = "https://github.com/curl/curl/archive/$(getvar CURL_VERSION "$vars").tar.gz";
    hash = "$(narhash "https://github.com/curl/curl/archive/$(getvar CURL_VERSION "$vars").tar.gz")";
  };

  "brotli-$(getvar BROTLI_VERSION "$vars").tar.gz" = fetchurl {
    url = "https://github.com/google/brotli/archive/refs/tags/v$(getvar BROTLI_VERSION "$vars").tar.gz";
    hash = "$(narhash "https://github.com/google/brotli/archive/refs/tags/v$(getvar BROTLI_VERSION "$vars").tar.gz")";
  };

  "boringssl-$(getvar BORING_SSL_COMMIT "$vars").zip" = fetchurl {
    url = "https://github.com/google/boringssl/archive/$(getvar BORING_SSL_COMMIT "$vars").zip";
    hash = "$(narhash "https://github.com/google/boringssl/archive/$(getvar BORING_SSL_COMMIT "$vars").zip")";
  };

  "nghttp2-$(getvar NGHTTP2_VERSION "$vars").tar.bz2" = fetchurl {
    url = "$(evalvar NGHTTP2_URL "$vars")";
    hash = "$(narhash "$(evalvar NGHTTP2_URL "$vars")")";
  };

  "ngtcp2-$(getvar NGTCP2_VERSION "$vars").tar.bz2" = fetchurl {
    url = "$(evalvar NGTCP2_URL "$vars")";
    hash = "$(narhash "$(evalvar NGTCP2_URL "$vars")")";
  };

  "nghttp3-$(getvar NGHTTP3_VERSION "$vars").tar.bz2" = fetchurl {
    url = "$(evalvar NGHTTP3_URL "$vars")";
    hash = "$(narhash "$(evalvar NGHTTP3_URL "$vars")")";
  };
}
EOF

curhash="$(nixeval "$attr.boringssl-go-modules.outputHash")"
newhash="$(vendorhash "$attr.boringssl-go-modules")"

if [ -n "$newhash" ] && [ "$curhash" != "$newhash" ]; then
    sed -i -e "s|\"$curhash\"|\"$newhash\"|" "$pkgpath"
else
    echo 'update.sh: New vendorHash same as old vendorHash, nothing to do.'
fi
