#!/bin/sh -f

alterator_api_version=1
cache_dir="/var/cache/alterator/ldap-groups"

. alterator-sh-functions
. alterator-openldap-functions

### cache

reset_cache()
{
  rm -rf -- "$cache_dir"
  mkdir -p -- "$cache_dir"
}

### member

member_list()
{
  local group="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  ldap-getent group "$group" memberUid|
	sed -e 's/,[[:blank:]]*/\n/g'>"$member_in_file"

  ldap-getent passwd '*' uid|
	while read user;do
	  fgrep -wqs "$user" "$member_in_file" || echo "$user"
	done>"$member_out_file"
}

member_list_in()
{
  local group="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  [ -f "$member_in_file" -a -f "$member_out_file" ] || member_list "$group"

  cat "$member_in_file"
}

member_list_out()
{
  local group="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  [ -f "$member_in_file" -a -f "$member_out_file" ] || member_list "$group"

  cat "$member_out_file"
}

member_add()
{
  local group="$1";shift
  local user="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  [ -f "$member_in_file" -a -f "$member_out_file" ] || member_list "$group"

  file_list_add "$member_in_file" "$user"
  file_list_del "$member_out_file" "$user"
}

member_del()
{
  local group="$1";shift
  local user="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  [ -f "$member_in_file" -a -f "$member_out_file" ] || member_list "$group"

  file_list_del "$member_in_file" "$user"
  file_list_add "$member_out_file" "$user"
}

member_reset()
{
  local group="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  rm -f -- "$member_in_file" "$member_out_file"
}

member_commit()
{
  local group="$1";shift
  local member_in_file="$cache_dir/member-in-$group"
  local member_out_file="$cache_dir/member-out-$group"

  [ -f "$member_in_file" -a -f "$member_out_file" ] || member_list "$group"

  if [ -s "$member_in_file" ]; then
    sed 's/.*/memberUid:&/' "$member_in_file"|ldap-groupmod replace "$group" > /dev/null
  else
    printf 'memberUid:\n'|ldap-groupmod replace "$group" > /dev/null
  fi
  member_reset "$group"
}

### e-mail

email_list()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  if [ -f "$email_file" ];then
	cat "$email_file"
  else
   ldap-getent group "$user" mail|
    sed -e 's/,[[:blank:]]*/\n/g'|
    tee "$email_file"
  fi
}

email_add()
{
  local user="$1";shift
  local email="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || email_list >/dev/null
  file_list_add "$email_file" "$email"
}

email_del()
{
  local user="$1";shift
  local email="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || email_list >/dev/null
  file_list_del "$email_file" "$email"
}

email_reset()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  rm -f -- "$email_file"
}

email_commit()
{
  local user="$1";shift
  local email_file="$cache_dir/email-$user"

  [ -f "$email_file" ] || return 0

  if [ -s "$email_file" ]; then
	sed 's/.*/mail:&/' "$email_file"|ldap-groupmod replace "$user" > /dev/null
  else
	printf 'mail:\n'|ldap-groupmod replace
  fi
  email_reset "$user"
}

### group

group_new()
{
    local r="$(ldap-groupadd "$1" 2>&1)"
    [ -n "$r" ] && write_error "$r" && return 1
    :
}

group_delete()
{
    local r="$(ldap-groupdel "$1" 2>&1)"
    [ -n "$r" ] && write_error "$r" && return 1
    :
}

set_dn_conf()
{
    local dn="$(system-auth status|cut -f2 -d' ')"
    [ -n "$dn" ] || fatal "set_dn_conf: couldn't detect dn"

    DN_CONF="$(/usr/sbin/ldap-dn find "$dn")"
    [ -f "$DN_CONF" ] || fatal "set_dn_conf: $DN_CONF doesn't exist"

    export DN_CONF
    base_rootdn_rootpw
}

set_dn_conf
reset_cache

on_message()
{
	case "$in_action" in
	type)
	    write_type_item	new_group	system-account-name
	    write_type_item	new_email	e-mail
	    ;;
	list)
	    ldap-getent group '*' cn|sort|write_enum
	    ;;
	delete)
	    [ -n "$in_group" ] || return
	    group_delete "$in_group"
	    ;;
	new)
	    [ -n "$in_new_group" ] || return
	    group_new "$in_new_group" || return
	    ;;
	member_list_in)
	    [ -n "$in_group" ] || return
	    member_list_in "$in_group"|write_enum
	    ;;
	member_list_out)
	    [ -n "$in_group" ] || return
	    member_list_out "$in_group"|write_enum
	    ;;
	member_add)
	    [ -n "$in_group" -a -n "$in_member_out" ] || return
	    member_add "$in_group" "$in_member_out"
	    ;;
	member_del)
	    [ -n "$in_group" -a -n "$in_member_in" ] || return
	    member_del "$in_group" "$in_member_in"
	    ;;
	member_commit)
	    [ -n "$in_group" ] || return
	    member_commit "$in_group"
	    ;;
	member_reset)
	    [ -n "$in_group" ] || return
	    member_reset "$in_group"
	    ;;
	email_list)
	    [ -n "$in_group" ] || return
	    email_list "$in_group" |write_enum
	    ;;
	email_add)
	    [ -n "$in_group" -a -n "$in_new_email" ] || return
	    email_add "$in_group" "$in_new_email"
	    ;;
	email_del)
	    [ -n "$in_group" -a -n "$in_email" ] || return
	    email_del "$in_group" "$in_email"
	    ;;
	email_commit)
	    [ -n "$in_group" ] || return
	    email_commit "$in_group"
	    ;;
	email_reset)
	    [ -n "$in_group" ] || return
	    email_reset "$in_group"
	    ;;
	esac
}

message_loop
