#!/bin/bash

if [ $# -ne 2 ]; then
  >&2 echo 'usage: update-kernel-config [repository] [kernel-name]'
  exit 2
fi

git_repo_path='/usr/src/archlinux32/packages/'
upstream_git_path='/usr/src/archlinux/packages'
vagrant_path=$(
  readlink -f ~/"virtual-boxes/archlinux32-test"
)

old_revision=$(
  sed -n '
    s/^# upstream git\( revision\)\?: *//
    T
    p
  ' "${git_repo_path}/$1/$2/PKGBUILD"
)

if [ -z "${old_revision}" ]; then
  >&2 echo 'Cannot determine old upstream git revision.'
  >&2 echo '"# upstream git revision: ..." line is missing.'
  exit 1
fi

config_names=$(
  git -C "${git_repo_path}/$1/$2" archive HEAD -- | \
    tar -t | \
    grep '^config\($\|\.\)' | \
    tr '\n' ' '
)

diff=$(
  git -C "${upstream_git_path}/$2/repos/$1-x86_64" diff "${old_revision}" HEAD -- config | \
    grep '^[+-].' | \
    grep -v '^+++\|^---'
)

if [ -z "${diff}" ]; then
  >&2 echo 'nothing changed.'
  exit 1
fi

for config_name in ${config_names}; do
  {
    grep -vxF "$(
      printf '%s\n' "${diff}" | \
        sed '
          s/^-//
          t
          d
        '
    )" "${git_repo_path}/$1/$2/${config_name}"
    printf '%s\n' "${diff}" | \
      sed '
        s/^+//
        t
        d
      '
  } | \
    sponge "${git_repo_path}/$1/$2/${config_name}"
done

sed -i '
  1 s/^#.*$/# upstream git revision: '"$(
    git -C "${upstream_git_path}" rev-parse HEAD
  )"'/
  s/'"$(
    git -C "${upstream_git_path}/$2/repos/$1-x86_64" archive "${old_revision}" -- config | \
      tar -Ox | \
      sha256sum | \
      awk '{print $1}'
  )"'/'"$(
    git -C "${upstream_git_path}/$2/repos/$1-x86_64" archive HEAD -- config | \
      tar -Ox | \
      sha256sum | \
      awk '{print $1}'
  )"'/g
  ' "${git_repo_path}/$1/$2/PKGBUILD"

if ssh -o ConnectTimeout=1 arch32-test true; then
  vm_is_running=true
else
  vm_is_running=false
fi

if ! ${vm_is_running}; then
  cd "${vagrant_path}"
  vagrant up
fi

{
  git -C "${upstream_git_path}/$2/repos/$1-x86_64" archive HEAD --
  for config_name in ${config_names}; do
    tar -c -C "${git_repo_path}/$1/$2" "${config_name}"
  done
} | \
  ssh arch32-test '
    rm -rf --one-file-system "'"$2"'"
    mkdir "'"$2"'"
    tar -xiC "'"$2"'"
  '
ssh arch32-test '
  cd "'"$2"'"
  cat >> PKGBUILD
  sed -i '"'"'
    '"$(
      for config_name in ${config_names}; do
        printf 's/'
        git -C "${git_repo_path}/$1/$2" archive HEAD -- "${config_name}" | \
          tar -Ox | \
          sha256sum | \
          awk '{print $1}' | \
          tr -d '\n'
        printf '/SKIP/g\n'
      done
    )"'
    /^arch=[^#]*any/!{
      /^arch=(/s/(/(i486 i686 pentium3 /
    }
    /make oldconfig/ s/^\s*#//
    s/^}$/return 1\n\0/
  '"'"' PKGBUILD
' < \
  "${git_repo_path}/$1/$2/PKGBUILD"
ssh arch32-test '
  cd "'"$2"'"
  eval "$(grep '"'"'^_srcname='"'"' PKGBUILD)"
  for config_name in '"${config_names}"'; do
    rm -rf --one-file-system src pkg
    if [ "${config_name}" = "config" ]; then
      makepkg -fcrs --asdeps --noconfirm
    else
      CARCH=${config_name#config.} makepkg -fcrs --asdeps --noconfirm
    fi
    mv src/${_srcname}/.config ${config_name}
  done
'
for config_name in ${config_names}; do
  scp "arch32-test:$2/${config_name}" "${git_repo_path}/$1/$2/"
done
ssh arch32-test '
  rm -rf --one-file-system "'"$2"'"
'
sed -i "$(
  for config_name in ${config_names}; do
    printf 's/'
    git -C "${git_repo_path}/$1/$2" archive HEAD -- "${config_name}" | \
      tar -Ox | \
      sha256sum | \
      awk '{print $1}' | \
      tr -d '\n'
    printf '/'
    sha256sum "${git_repo_path}/$1/$2/${config_name}" | \
      awk '{print $1}' | \
      tr -d '\n'
    printf '/g\n'
  done
)" "${git_repo_path}/$1/$2/PKGBUILD"
git -C "${git_repo_path}/$1/$2" commit PKGBUILD ${config_names} -m "$1/$2: new version => new config => new checksum"
if ! ${vm_is_running}; then
  ssh arch32-test 'sudo poweroff'
  err=$?
  if [ ${err} -eq 255 ]; then
    err=0
  fi
  exit ${err}
fi