const self = "pkgs/packages/webserver/package.nix"
let tmpdir = mktemp -d webserver-update.XXXXXXXXXX

let dependencies = {
  fontsource-scss: (prefetch-npm @fontsource-utils/scss)
  fontsource-arimo: (prefetch-npm @fontsource-variable/arimo)
  fontsource-nunito: (prefetch-npm @fontsource-variable/nunito)

  bulma: (prefetch-github jgthms bulma)
  hack-font: (prefetch-github source-foundry Hack)
}

cd (git rev-parse --show-toplevel)

$dependencies | items {|name, metadata| $metadata | update-dependency $name }

rm -r $tmpdir

cd (dirname $self)
cargo update

def prefetch-npm [package: string] {
  let metadata = http get $'https://registry.npmjs.org/($package)'
  let version = $metadata.dist-tags.latest
  let url = ($metadata.versions | get $version).dist.tarball
  let tarball = ($tmpdir | path join "package.tgz")

  http get $url | save -f $tarball

  let hash = nix hash file $tarball

  {
    url: $url
    version: $version
    hash: $hash
  }
}

def prefetch-github [owner: string, repo: string] {
  let metadata = http get $'https://api.github.com/repos/($owner)/($repo)/releases/latest'
  let prefetch = nix-prefetch-github --rev $metadata.tag_name --json $owner $repo | from json
  $prefetch | select hash | insert version ($metadata.name | str trim --left --char v)
}

def update-dependency [dependency_name: string] {
  const replace_attribute_template = "
    id: update-attribute
    language: nix
    utils:
      is-attribute:
        kind: string_fragment
        inside:
          kind: binding
          stopBy: end
          has:
            field: attrpath
            regex: '{attribute}'

    rule:
      matches: is-attribute
      not:
        regex: '{replacement}'
      inside:
        kind: binding
        stopBy: end
        has:
          field: attrpath
          regex: '{dependency_name}'

    fix: '{replacement}'"

  let template_data = (
    $in | if ($in has url) {
      [{attribute: url replacement: $in.url}]
    } else { [] }
  ) ++ [
    {attribute: version replacement: $in.version}
    {attribute: hash replacement: $in.hash}
  ];

  let ast_grep_rule = (
    $template_data
    | each { $in | insert dependency_name $dependency_name | format pattern $replace_attribute_template }
    | str join "\n---\n"
  )

  ast-grep scan --update-all --inline-rules $ast_grep_rule $self
}
