#! /bin/bash

function pre_req()
{
source script/discover_package_manager
source script/discover_os
source script/solve_autoconf
source script/solve_gpp
source script/solve_gfortran
source script/solve_cmake
source script/solve_git
source script/solve_wget
source script/solve_automake
source script/solve_brew
source script/solve_libtool
source script/detect_gcc
source script/detect_osx
source script/show_solutions
source script/detect_fortran

discover_os
discover_package_manager $platform
pcman=$discover_package_manager_ret

if [ x"$platform" = x"osx" -a x"$pcman" = x""  ]; then
  echo -e "\033[30;43;5;1m WARNING \033[0m No package manager has been found on this system"
  solve_brew $platform

  discover_package_manager $platform
  pcman=$discover_package_manager_ret
  if [ x"$pcman" != x"brew" ]; then
    echo -e "brew \033[91;5;1m FAILED \033[0m"
  fi
fi

### Additional package required for apt-get based distros
if [ x"$platform" = x"linux" -a x"$pcman" = x"sudo apt-get"  ]; then
  dpkg-query -l libbz2-dev
  ret1=$?
  dpkg-query -l python-dev
  ret2=$?
  dpkg-query -l libxml2-dev
  ret3=$?
  dpkg-query -l libxslt-dev
  ret4=$?
  if [ $ret1 -ne 0 -o $ret2 -ne 0 -o $ret3 -ne 0 -o $ret4 -ne 0 ]; then
    echo "OpenFPM require additional packages in order to install correctly"
    commands[0]="$pcman install libbz2-dev python-dev libxml2-dev libxslt-dev"
    possible_solutions "${commands[@]}"
  fi
fi

### Additional package required for yum based distros
if [ x"$platform" = x"linux" -a x"$pcman" = x"yum"  ]; then
  rpm -V bzip2-devel
  ret1=$?
  rpm -V python-devel
  ret2=$?
  rpm -V libxml2-devel
  ret3=$?
  rpm -V libxslt-devel
  ret4=$?
  if [ $ret1 -ne 0 -o $ret2 -ne 0 -o $ret3 -ne 0 -o $ret4 -ne 0 ]; then
    echo "OpenFPM require additional packages in order to install correctly"
    commands[0]="su -c \"$pcman install bzip2-devel python-devel libxml2-devel libxslt-devel\""
    commands[1]="sudo $pcman install bzip2-devel python-devel libxml2-devel libxslt-devel"
    possible_solutions "${commands[@]}"
  fi
fi

command -v cmake >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo >&2
  echo -e "cmake\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require cmake but it's not installed, searching a solution... "
  solve_cmake $platform
  command -v cmake >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo -e "cmake\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "cmake\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "cmake\033[92;1m SUCCESS \033[0m"
fi

command -v wget >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo >&2
  echo -e "wget\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require wget but it's not installed, searching a solution... "
  solve_wget $platform
  command -v wget >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo -e "wget\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "wget\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "wget \033[92;1m SUCCESS \033[0m"
fi

command -v git >/dev/null 2>&1
if [ $? -ne 0 ]; then 
  echo >&2
  echo -e "git\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require git but it's not installed, searching a solution... "
  solve_git $platform
  command -v git >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo -e "git\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "git\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "git \033[92;1m SUCCESS \033[0m"
fi

command -v autoconf >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo >&2
  echo -e "autoconf\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require autoconf but it's not installed, searching a solution..."
  solve_autoconf $platform
  command -v autoheader >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo -e "autoconf\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "autoconf\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "autoconf\033[92;1m SUCCESS \033[0m"
fi

command -v automake >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo >&2
  echo -e "automake\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require automake but it's not installed, searching a solution..."
  solve_automake $platform
  command -v automake >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo "automake\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "automake\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "automake\033[92;1m SUCCESS \033[0m"
fi


command -v libtoolize  >/dev/null 2>&1
opt1=$?
command -v glibtoolize  >/dev/null 2>&1
opt2=$?
if [ $opt1 -ne 0 -a $opt2 -ne 0 ]; then
  echo >&2
  echo -e "libtool\033[91;5;1m FAILED \033[0m"
  echo "OpenFPM require libtool but it's not installed, searching a solution..."
  solve_libtool $platform
  command -v libtoolize  >/dev/null 2>&1
  opt1=$?
  command -v glibtoolize  >/dev/null 2>&1
  opt2=$?
  if [ $opt1 -ne 0 -a $opt2 -ne 0 ]; then
    echo -e "libtool\033[91;5;1m FAILED \033[0m"
    exit 1
  else
    echo -e "libtool\033[92;1m SUCCESS \033[0m"
  fi
else
  echo -e "libtool\033[92;1m SUCCESS \033[0m"
fi

#### Detecting g++

detect_gcc_or_clang g++
if [ $dgc_ret -eq 0 ]; then
  echo -e "g++ \033[91;5;1m FAILED \033[0m"
  solve_gpp $platform
  detect_gcc_or_clang $compiler_gpp
  if [ $dgc_ret -eq 0 ]; then
    exit 1
  fi
elif [ $dgc_ret -eq 2 ]; then
  detect_osx $platform
  if [ $dosx_ret -eq 1 ]; then
    echo -e "\033[30;43;5;1m------------------------------- WARNING --------------------------------\033[0m"
    echo "g++ seem to be present, but we failed to detect the version. Your system $dosx_major.$dosx_middle.$dosx_minor seem to be recent enough, so we will continue the installation"
    sleep 10    
  fi
fi

#### Detection gfortran

detect_fortran gfortran
if [ $dgc_ret -eq 0 ]; then
  echo -e "gfortran\033[91;5;1m FAILED \033[0m"
  solve_gfortran $platform
  detect_fortran $compiler_fortran
  if [ $dgc_ret -eq 0 ]; then
    exit 1
  fi
else
  echo -e "gfortran \033[92;1m SUCCESS \033[0m"
fi


MPI_valid=no
command -v mpirun >/dev/null 2>&1
if [ $? -ne 0 ]; then
  echo -e "No MPI"
else
  # Here we check if we are running openmpi  mpich or unknown

  version=$(mpirun --version 2>&1 | grep mpirun | sed 's/.*Open MPI.*/openmpi/g')
  if [ x"$version" == x"" ]; then
    version=$(mpirun --version 2>&1 | grep HYDRA | sed 's/HYDRA.*/mpich/g')
  fi

  if [ x"$version" == x"openmpi" ]; then

    major=$(mpirun --version 2>&1 | grep mpirun | sed 's/.*\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1/g')
    middle=$(mpirun --version 2>&1 | grep mpirun | sed 's/.*\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\2/g')
    minor=$(mpirun --version 2>&1 | grep mpirun | sed 's/.*\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\3/g')
    if [ $major -gt 1 ]; then
      echo -e "openmpi $major.$middle.$minor \033[92;1m SUCCESS \033[0m"
      MPI_valid=yes
    elif [ $major -lt 1 ]; then
      echo -e "openmpi $major.$middle.$minor \033[33;5;1m WARNING \033[0m is too old, 1.8.1 at least required, (Automatic fix activated)"
    elif [ $middle -gt 8  ]; then
      echo -e "openmpi $major.$middle.$minor \033[92;1m SUCCESS \033[0m"
      MPI_valid=yes
    elif [ $middle -lt 8 ]; then
      echo -e "opnmpi $major.$middle.$minor \033[33;5;1m WARNING \033[0m is too old, 1.8.1 at least required (Automatic fix activated)"
    elif [ $minor -gt 0  ]; then
      echo -e "openmpi $major.$middle.$minor \033[92;1m SUCCESS \033[0m"
      MPI_valid=yes
    else
      echo -e "openmpi $major.$middle.$minor \033[33;5;1m WARNING \033[0m is too old, 1.8.1 at least required, (Automatic fix activated)"
    fi
  elif [ x"$version" == x"mpich" ]; then 
    major=$(mpirun --version 2>&1 | grep Version | sed 's/.*\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1/g')
    middle=$(mpirun --version 2>&1 | grep Version | sed 's/.*\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\2/g')
    if [ $major -gt 3 ]; then
      echo -e "mpich $major.$middle \033[92;1m SUCCESS \033[0m"
      MPI_valid=yes
    elif [ $major -lt 3 ]; then
      echo -e "mpich $major.$middle \033[33;5;1m WARNING \033[0m is too old, 3.2 at least required, (Automatic fix activated)"
    elif [ $middle -gt 1  ]; then
      echo -e "mpich $major.$middle \033[92;1m SUCCESS \033[0m"
      MPI_valid=yes
    elif [ $middle -lt 1 ]; then
      echo -e "mpich $major.$middle \033[33;5;1m WARNING \033[0m is too old, 3.2 at least required (Automatic fix activated)"
    else
      echo -e "mpich $major.$middle \033[33;5;1m WARNING \033[0m is too old, 3.2 at least required, (Automatic fix activated)"
    fi
  else

    #### Unkown version of MPI print a warning

    echo -e "\033[43;30;1;5mWARNING: \033[0m Found an unkown version of MPI, OpenFPM work with any MPI version that implement MPI-3.0 interface. If you know that the installed MPI implement the MPI-3.0 interface choose 1) continue. If you are not sure, or you do not even know what this message mean choose 2) install OpenMPI"

    echo "1) Continue"
    echo "2) Install OpenMPI"

    choose=1
    if [ $sq -eq 0 ]; then
      read choose
    fi

    if [ $choose -eq 1 ]; then
      MPI_valid=yes
    fi

  fi
fi

if [ x"$MPI_valid" == x"yes"  ]; then
  ## Check for potential problem in the MPI installation

  if [ -d $1/MPI ]; then
    where_mpi=$(which mpic++)

    if [ x"$where_mpi" != x"$1/MPI/bin/mpic++" ]; then
      echo -e "\033[91;5;1m MPI instalation: CONFLICT \033[0m"
        echo "Performing a \"which mpic++\", we found that you have installed one system wide MPI "
        echo -e "\033[1m $where_mpi \033[0m"
        echo "this MPI has priority over OpenFPM MPI installation in: "
	echo -e "\033[1m $1/MPI/bin/mpic++ \033[0m"
	echo "Such configuration is not supported, one MPI must be uniquely selected"
        echo "The possible solutions are: "
        echo -e "\033[1m 1) Set your PATH to give priority to $1/MPI/bin \033[0m"
        echo -e "\033[1m 2) Eliminate OpenFPM MPI removing $1/MPI \033[0m"
        echo -e "\033[1m 3) Eliminate the system wide MPI \033[0m"
      exit 1
    fi
  fi
fi

}