#!/bin/bash
#
# Tvheadend configure script
#
# Copyright (c) 2012 Adam Sutton <dev@adamsutton.me.uk>
#

# ###########################################################################
# Setup
# ###########################################################################

ROOTDIR=$(cd "$(dirname "$0")"; pwd)
test -z "$PKG_CONFIG" && PKG_CONFIG=pkg-config

#
# Options
#

OPTIONS=(
  "cwc:yes"
  "capmt:yes"
  "constcw:yes"
  "linuxdvb:yes"
  "satip_server:yes"
  "satip_client:yes"
  "hdhomerun_client:no"
  "hdhomerun_static:yes"
  "iptv:yes"
  "tsfile:yes"
  "dvbscan:yes"
  "timeshift:yes"
  "trace:yes"
  "imagecache:auto"
  "avahi:auto"
  "zlib:auto"
  "libav:auto"
  "libffmpeg_static:no"
  "libffmpeg_static_x264:yes"
  "inotify:auto"
  "epoll:auto"
  "uriparser:auto"
  "ccache:auto"
  "tvhcsa:auto"
  "bundle:no"
  "dvbcsa:no"
  "dvben50221:auto"
  "kqueue:no"
  "dbus_1:auto"
  "android:no"
  "tsdebug:no"
  "gtimer_check:no"
)

#
# Begin
#

. "$ROOTDIR/support/configure.inc"

case "$ROOTDIR" in
  *\ * ) die "The source directory contains a space. It is not supported."
esac

# ###########################################################################
# Parse arguments
# ###########################################################################
opt=
val=
for opt do
  val=${opt#*=}
  opt=${opt%=*}
  opt=${opt#*--}
  case "$opt" in
    help)
      show_help
      ;;
    *dir|prefix)
      eval "$opt=$val"
      ;;
    gzip)
      eval "$(toupper ${opt}CMD)=\"$val\""
      ;;
    cc|cflags|ldflags|arch|cpu|platform|python|bzip2)
      eval "$(toupper $opt)=\"$val\""
      ;;
    enable-*)
      opt=${opt#*-}
      enable $opt 1
      ;;
    disable-*)
      opt=${opt#*-}
      disable $opt 1
      ;;
  esac
done

# ###########################################################################
# Checks
# ###########################################################################

echo "Checking support/features"

#
# Compiler
#

# Use ccache
if enabled_or_auto ccache; then
  which ccache &> /dev/null
  if [ $? -eq 0 ]; then
    echo "$CC" | grep -q ccache || CC="ccache $CC"
    enable ccache
  elif enabled ccache; then
    die "ccache not found, try --disable-ccache"
  fi
fi

# Valiate compiler
check_cc || die 'No C compiler found'
check_cc_header execinfo
check_cc_option mmx
check_cc_option sse2

if check_cc '
#if !defined(__clang__)
#error this is not clang
#endif
'; then
  COMPILER=clang
else
  COMPILER=gcc
fi

check_cc_snippet getloadavg '#include <stdlib.h> 
void test() { getloadavg(NULL,0); }'

check_cc_snippet atomic64 '#include <stdint.h>
uint64_t test(uint64_t *ptr){
return __sync_fetch_and_add(ptr, 1);
}'

check_cc_snippet lockowner '
#include <sys/syscall.h>
#include <unistd.h>
#include <pthread.h>
#define TEST test
int ok = 1;
void *lockowner ( void *p)
{
  pthread_mutex_t lock;
  pthread_mutex_init(&lock, NULL);
  pthread_mutex_lock(&lock);
  if (lock.__data.__owner == syscall(SYS_gettid))
    ok = 0;
  return NULL;
}
int test ( void )
{
  pthread_t tid;
  pthread_create(&tid, NULL, lockowner, NULL);
  pthread_join(tid, NULL);
  return ok;
}' -lpthread

check_cc_snippet qsort_r '
#include <stdlib.h>
#define TEST test
int test(void)
{
  qsort_r(NULL, 0, 0, NULL, NULL);
  return 0;
}
'

check_cc_snippet stime '
#include <time.h>
#define TEST test
int test(void)
{
  time_t t = 1;
  stime(&t);
  return 0;
}
'

check_cc_snippet recvmmsg '
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/socket.h>
#define TEST test
int test(void)
{
  recvmmsg(0, NULL, 0, 0, NULL);
  return 0;
}
'

check_cc_snippet sendmmsg '
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/socket.h>
#define TEST test
int test(void)
{
  sendmmsg(0, NULL, 0, 0);
  return 0;
}
'

check_cc_snippet libiconv '
#include <iconv.h>
int test(void)
{
  iconv_t ic = iconv_open("ASCII", "ASCII");
  return 0;
}
' -liconv

if enabled_or_auto dvben50221; then
  check_cc_snippet libdvben50221 '
  #include <libdvben50221/en50221_session.h>
  #define TEST test
  int test(void)
  {
    struct en50221_transport_layer *tl = en50221_tl_create(5, 32);
    return 0;
  }
  ' '-ldvben50221 -ldvbapi -lucsi'
  if enabled libdvben50221; then
    enable dvben50221
  else
    disable dvben50221
  fi
fi

#
# Python
#
check_py || echo 'WARN: no python binary found'
check_py_import gzip

#
# Binaries
#
check_bin ${GZIPCMD} || die 'WARN: no gzip binary found'
check_bin ${BZIP2} || echo 'WARN: no bzip2 binary found'

#
# SSL
#
if [ ${PLATFORM} = "freebsd" ]; then
  # FreeBSD has libssl in base
  enable ssl
elif check_pkg openssl || check_pkg libssl; then
  enable ssl
elif check_cc_header 'openssl/ssl' ssl; then
  enable ssl
else
  die "SSL development support not found"
fi

#
# OS X
#
if [ ${PLATFORM} = "darwin" ]; then
  disable linuxdvb
  disable avahi
  enable bonjour
fi

#
# DVB API
#
check_cc_header 'linux/dvb/version' linuxdvbapi
if enabled_or_auto linuxdvb; then
  if enabled linuxdvbapi; then
    enable linuxdvb
  elif enabled linuxdvb; then
    die "Linux DVB API not found (use --disable-linuxdvb)"
  fi
fi

#
# HDHomeRun - libhdhomerun
#
if enabled hdhomerun_static; then

  enable hdhomerun_client

else

  if enabled_or_auto hdhomerun_client; then
    if check_cc_header 'libhdhomerun/hdhomerun' libhdhomerun; then
      enable  hdhomerun_client
      LDFLAGS="$LDFLAGS -lhdhomerun"
    fi
  fi

fi

#
# Gzip
#
if enabled_or_auto zlib; then
  if check_pkg zlib; then
    enable zlib
  elif enabled zlib; then
    die "Zlib development support not found (use --disable-zlib)"
  fi
fi

#
# SAT>IP server
#
if enabled_or_auto satip_server; then
  enable upnp
fi

#
# SAT>IP client
#
if enabled_or_auto satip_client; then
  enable upnp
fi

#
# uriparser
#
if enabled_or_auto uriparser; then
  if check_pkg liburiparser; then
    enable uriparser
  elif enabled uriparser; then
    die "liburiparser development support not found (use --disable-uriparser)"
  fi
fi

#
# Bundling
#
if enabled bundle; then
  if enabled zlib && ! enabled py_gzip; then
    die "Python gzip module not found (use --disable-zlib or --disable-bundle)"
  fi
fi

#
# Avahi
#
if enabled_or_auto avahi; then
  if check_pkg avahi-client; then
    enable avahi
  elif enabled avahi; then
    die "Avahi development support not found (use --disable-avahi)"
  fi
fi

#
# libav
#
if enabled libffmpeg_static; then

  enable libav
  has_libav=true

else

  if enabled_or_auto libav; then
    has_libav=true

    ffmpeg=$(${PKG_CONFIG} --modversion libavcodec | cut -d '.' -f 3)
    test -z "$ffmpeg" && ffmpeg=0
    printf "$TAB" "checking for ffmpeg libraries ..."
    if test $ffmpeg -lt 100; then
      ffmpeg=
      echo "fail"
    else
      ffmpeg=yes
      echo "ok"
    fi

    if test "$ffmpeg" == "yes"; then

      #
      # check for version n1.2+
      #
      if $has_libav && ! check_pkg libavcodec ">=55.18.102"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavutil ">=52.38.100"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavformat ">=55.12.100"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libswscale ">=2.3.100"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavresample ">=1.1.0"; then
        has_libav=false
      fi

    else

      #
      # check for version v10+
      #

      if $has_libav && ! check_pkg libavcodec ">=55.34.1"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavutil ">=53.3.0"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavformat ">=55.12.0"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libswscale ">=2.1.2"; then
        has_libav=false
      fi

      if $has_libav && ! check_pkg libavresample ">=1.1.0"; then
        has_libav=false
      fi

    fi

    if $has_libav; then
      enable libav
    else
      echo "WARNING: none or old libav or libffmpeg libraries were detected"
      echo "         * use --disable-libav or --enable-libffmpeg_static"
      echo "         ** supported ffmpeg libs n1.2+"
      echo "         ** supported libav  libs v10+"
      if enabled libav; then
        die "libav development support not found"
      fi
    fi
  fi

fi

#
# Inotify
#
if enabled_or_auto inotify; then
  if check_cc_header "sys/inotify" inotify_h; then
    enable inotify
  elif enabled inotify; then
    die "Inotify support not found (use --disable-inotify)"
  fi
fi

#
# libdvbcsa, tvhcsa
#
if enabled cwc || enabled capmt || enabled constcw; then
  enable tvhcsa
  if enabled dvbcsa; then
    (check_cc_header "dvbcsa/dvbcsa" dvbcsa_h &&\
     check_cc_lib    dvbcsa dvbcsa_l) ||\
    die "Failed to find dvbcsa support (use --disable-dvbcsa)"
    LDFLAGS="$LDFLAGS -ldvbcsa"
  fi
fi

#
# libdvben50221
#
if enabled libdvben50221; then
  LDFLAGS="$LDFLAGS -ldvben50221 -ldvbapi -lucsi"
  enable linuxdvb_ca
fi

#
# Icon caching
#
if enabled_or_auto imagecache; then
  enable imagecache
fi

#
# DVB scan
#
if enabled dvbscan; then
  printf "${TAB}" "fetching dvb-scan files ..."
  "${ROOTDIR}/support/getmuxlist"
  if [ $? -ne 0 ]; then
    echo "fail"
    die "Failed to fetch dvb-scan data (use --disable-dvbscan)"
  fi
  echo "ok"
fi

#
# epoll
#
if [ ${PLATFORM} = "linux" ]; then
  enable epoll
fi

#
# kqueue
#
if [ ${PLATFORM} = "freebsd" ] || [ ${PLATFORM} = "darwin" ]; then
  enable kqueue
fi

#
# MPEGTS support
#
disable mpegts
disable mpegts_dvb
if enabled linuxdvb || enabled iptv || enabled tsfile || enabled satip_client || \
   enabled hdhomerun_client || enabled satip_server;
then
  enable mpegts
fi
if enabled linuxdvb || enabled satip_client || enabled hdhomerun_client || enabled satip_server; then
  enable mpegts_dvb
fi

#
# DBus
#
if enabled_or_auto dbus_1; then
  if check_pkg dbus-1; then
    enable dbus_1
  elif enabled dbus-1; then
    die "DBus-1 development support not found (use --disable-dbus-1)"
  fi
fi

#
# TSDebug
#
if enabled_or_auto tsdebug; then
  enable mpegts_dvb
fi


# ###########################################################################
# Write config
# ###########################################################################

# Write config
write_config
cat >> "${CONFIG_H}" <<EOF
#define TVHEADEND_DATADIR "$(eval echo ${datadir})/tvheadend"
EOF

# Output config
print_config
echo "Final Binary:"
echo "  $BUILDDIR/tvheadend"
echo ""
echo "Tvheadend Data Directory:"
echo "  $(eval echo ${datadir}/tvheadend)"
echo ""
