#!/bin/sh
# Test for linux distributions.
set -e

. /usr/share/os-prober/common.sh

partition="$1"
dir="$2"
type="$3"

# This test is inaccurate, but given separate / and /boot partitions and the
# fact that only some architectures have ld-linux.so, I can't see anything
# better. Make sure this test has a high number so that more accurate tests
# can come first.
# TODO: look for ld-linux.so on arches that have it

# hierarchy

# based or forked

# chakra-release  # arch
# arch-release

# kanotix_version # debian
# kdemar-release # debian, knoppix
# knoppix_version  # debian
# debian_version

# blackPanther-release # mandriva
# pclinuxos-release # mandrake, mandriva
# mandriva-release # mandrake, mandrakelinux, redhat
# mandrakelinux-release
# mandrake-release

# altlinux-release # redhat
# yellowdog-release # centos, fedora
# centos-release # redhat, fedora
# asplinux-release # fedora
# engarde-release # fedora
# e-smith-release # fedora
# magic-release # fedora
# trustix-release # fedora
# fedora-release # redhat
# startcom-release # redhat
# redhat-release

# meego-release # moblin
# moblin-release

# slax-version # slackware
# zenwalk-version # slackware
# slackware-version

# sles-release # suse
# SuSE-release

# independent

# ark-release
# caos-release
# frugalware-release
# gentoo-release
# lfs-release
# pardus-release
# pld-release
# turbolinux-release
# vine-release
# whitebox-release

# reserved
# system-release

based_or_forked1='SuSE-release sles-release slackware-version zenwalk-version slax-version moblin-release meego-release'
based_or_forked2='redhat-release startcom-release fedora-release trustix-release magic-release e-smith-release engarde-release asplinux-release centos-release yellowdog-release altlinux-release'
based_or_forked3='mandrake-release mandrakelinux-release mandriva-release pclinuxos-release blackPanther-release'
based_or_forked4='debian_version knoppix_version kdemar-release kanotix_version arch-release chakra-release'

independant='whitebox-release vine-release turbolinux-release pld-release pardus-release lfs-release gentoo-release frugalware-release caos-release ark-release'

reserved='system-release'

known_distro="$reserved $independant $based_or_forked1 $based_or_forked2 $based_or_forked3 $based_or_forked4"

find_distro_info() {
  found_distro=

  pattern='_version -version -release'

  for pat in $pattern; do

    for distro in $( ls -tr $dir/etc/*$pat 2>/dev/null ); do
      if [ -L $distro ]; then
        continue
      fi

      distro=$(basename $distro)

      if [ "$distro" = 'lsb-release' ]; then
        continue
      fi

      found_distro="$found_distro$distro "
    done

  done
}

prepare_label() {
  label=$(echo $1 | gawk '{ match($0, /(.+)(_version|-version|-release)/, dist); print dist[1] }')
}

prepare_title() {
  title="$(head -1 $dir/etc/$1)"

  title=$(echo $title | gawk '{ match($0, /^[[:space:]]*(.*)[[:space:]]*$/, title); print title[1] }')

  if [ ! -z $(echo $title | awk '/^([[:graph:]]+)$/ { print $0 }') ] || [ -z "$title" ]; then
    tlabel=$(echo $label | gawk '{ match($0, /(.)(.*)/, title); print toupper(title[1]) tolower(title[2]) }')

    if [ ! -z "$title" ]; then
      title=" ($title)"
    fi

    title="${tlabel} GNU/Linux$title"
  fi
}

prepare_distro_info() {
  if [ ! -z "$found_distro" ]; then
    mdistro=

    for kdistro in $known_distro; do
      for fdistro in $found_distro; do
        if [ "$kdistro" = "$fdistro" ]; then
          mdistro=$kdistro
          found_distro=$(echo $found_distro | sed "s|$fdistro||")
          break
        fi
      done

      if [ -z "$found_distro" ]; then
        break
      fi
    done

    if [ -z "$found_distro" ]; then
      distro=$mdistro
    else
      distro=$(echo $found_distro | awk '{ print $NF }')
    fi

    rdistro=$distro

    if [ "$distro" = "debian_version" ] &&
       [ -f '/etc/dpkg/origins/ubuntu' ]; then
      distro='ubuntu_version'
    fi

    prepare_label $distro
    prepare_title $rdistro $label
  else
    label='Linux'
    title='unknown Linux distribution'
  fi
}

if ls $dir/lib*/ld*.so* >/dev/null 2>/dev/null; then
  find_distro_info

  prepare_distro_info

  label="$(count_next_label "$label")"
  echo "$partition:$title:$label:linux"

  exit 0
else
  exit 1
fi
