###################################################
# A basic cascade-make to install the Crypt::LE perl package required for ZeroSSL, to be used to get an https certificate on Mac
#
# Crypt::LE depends on the following packages:
# - Crypt::OpenSSL::Bignum, which needs openssl/err.h
#   for which we need to set C_INCLUDE_PATH=$GSDL3SRCHOME/bin/darwin/openssl/include
#   see https://www.perlmonks.org/?node_id=1181472
#      "If includes arent in default compiler findable directories, let the user add any extra directories, like he is supposed to
#       http://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html like C_INCLUDE_PATH/LIBRARY_PATH... "
# - JSON::MaybeXS, which depends on
#     - JSON::PP
# - Time::Piece
# - HTTP::Tiny
# - Module::Load
# - Log::Log4perl
#
#
# Compiling AND INSTALLING of all packages takes place in the temporary cpan/tmp folder. A select subset of the compiled/installed
# products are then copied into their final destinations:
# - For regular packages, need to put the relevant products (the package folder inside the lib folder) into cpan, maintaining any
# existing folder structure.
# - However, for all packages that contain .bundle (mac, or .so for linux) and .xs or .bs bootstrap files, need to put the relevant
# products (both the "auto" and package folder inside the lib folder) into cpan/perl-<version> ($PERL_FOLDER, e.g. "perl-5.18").
# In this case, both Crypt::OpenSSL and Time::Piece once compiled up require this second treatment.
#
# Compiling as well as RUNNING the final Crypt::LE's le.pl executable requires PERL5LIB to have both the cpan and its $PERL_FOLDER
# subdirectory included in env var PERL5LIB.
#
###################################################

if [ "x$1" = "x--help" ] || [ "x$1" = "x-h" ]; then
    echo "Usage: $0 [--clean|--keep|--help|-h]"
    echo "  Run without flags to compile and remove unnecessary stuff at the end."
    echo "  Run with --keep to retain the cpan/tmp subdir at compilation's end." 
    echo "  Run with --clean to remove all traces of compilation completely so you can recompile from scratch"
    echo "  Run with --help/-h to see this Usage statement again"
    exit 0
fi

if [ "x$GSDL3SRCHOME" = "x" ] ; then
    echo "GSDL3SRCHOME not set, sourcing gs3-setup.sh"
    echo ""
    cd ../../..
    source ./gs3-setup.sh
    cd $GSDLHOME/perllib/cpan
fi

echo ""
echo "**************************"

CPAN_DIR=$GSDLHOME/perllib/cpan
OLD_PERL5LIB=$PERL5LIB

# PERL_FOLDER is something like "perl-5.18" (even if the full version number is 5.18.2)
PERL_FOLDER=`perl -e 'print "perl-5.".substr($],3,2);'`

# make the dirs cpan/$PERL_FOLDER and its subdir auto if they don't already exist
mkdir -p $CPAN_DIR/$PERL_FOLDER/auto

# dependencies are not found if PERL5LIB is simply set to cpan. PERL5LIB Needs to specifically be exported
export PERL5LIB=$CPAN_DIR:$CPAN_DIR/$PERL_FOLDER:$PERL5LIB

#echo "**** PERL5LIB is $PERL5LIB"


WGET_FLAGS=--no-check-certificate
# folder where we'll put the downloaded files, the compile products and the temporary install products
# after everything is installed there, we copy just the relevant installed files to their final locations
# then the tmp file gets deleted
TEMP_DIR=$CPAN_DIR/tmp-crypt-le


OLD_C_INCLUDE_PATH=$C_INCLUDE_PATH

# if clean was passed in
if [ "x$1" = "x--clean" ] ; then
    cd $CPAN_DIR
    rm -rf $PERL_FOLDER/Crypt $PERL_FOLDER/Time $PERL_FOLDER/auto/Crypt $PERL_FOLDER/auto/Time Log JSON/MaybeXS.pm Log Module JSON/PP.pm JSON/PP Crypt/LE Crypt/LE.pm
    mv JSON/PP.old JSON/PP
    mv JSON/PP.pm_old JSON/PP.pm
    rm -rf $TEMP_DIR
    echo "Done cleaning Crypt::LE related packages"
    exit 0
fi

mkdir -p $TEMP_DIR
# We'll download, unpack and compile (Makefile.PL, make and make install) packages into TEMP_DIR
# before copying the necessary components to their final locations
cd $TEMP_DIR


# First run through the dependencies and then finally Crypt::LE itself

# 1 https://metacpan.org/pod/Crypt::OpenSSL::Bignum
if [ ! -d "$CPAN_DIR/$PERL_FOLDER/Crypt/OpenSSL/Bignum" ]; then
    CRYPT_OPENSSL_BIGNUM=Crypt-OpenSSL-Bignum
    CRYPT_OPENSSL_BIGNUM_VER=$CRYPT_OPENSSL_BIGNUM-0.09
    echo "+ Installing $CRYPT_OPENSSL_BIGNUM"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/K/KM/KMX/$CRYPT_OPENSSL_BIGNUM_VER.tar.gz
    tar -xvzf $CRYPT_OPENSSL_BIGNUM_VER.tar.gz
    
    export C_INCLUDE_PATH=$GSDL3SRCHOME/bin/darwin/openssl/include
    cd $CRYPT_OPENSSL_BIGNUM_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$CRYPT_OPENSSL_BIGNUM
    make
    make install
    #cp -r $TEMP_DIR/$CRYPT_OPENSSL_BIGNUM/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/Crypt/OpenSSL $CPAN_DIR/Crypt/.
    cp -r $TEMP_DIR/Crypt-OpenSSL-Bignum/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/Crypt $CPAN_DIR/$PERL_FOLDER/.
    cp -r $TEMP_DIR/Crypt-OpenSSL-Bignum/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/auto/Crypt $CPAN_DIR/$PERL_FOLDER/auto/.

    C_INCLUDE_PATH=
    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/Crypt/OpenSSL/Bignum already exists, not installing"
fi


# 2a https://metacpan.org/pod/JSON::PP
# which is the minimum dependency for JSON::MaybeXS

if [ ! -f "$CPAN_DIR/JSON/PP.pm_old" ]; then
    mv $CPAN_DIR/JSON/PP $CPAN_DIR/JSON/PP.old
    mv $CPAN_DIR/JSON/PP.pm $CPAN_DIR/JSON/PP.pm_old

    JSON_PP=JSON-PP
    JSON_PP_VER=$JSON_PP-2.97001
    echo "+ Installing $JSON_PP"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/I/IS/ISHIGAKI/$JSON_PP_VER.tar.gz
    tar -xvzf $JSON_PP_VER.tar.gz

    cd $JSON_PP_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$JSON_PP
    make
    make install
    cp -r $TEMP_DIR/$JSON_PP/lib/perl5/site_perl/JSON/* JSON $CPAN_DIR/JSON/.

    cd $TEMP_DIR
else
    echo "*** The new $CPAN_DIR/JSON/PP.pm already exists, not installing"
fi


# 2 https://metacpan.org/pod/JSON::MaybeXS

if [ ! -f "$CPAN_DIR/JSON/MaybeXS.pm" ]; then
    JSON_MAYBEXS=JSON-MaybeXS
    JSON_MAYBEXS_VER=$JSON_MAYBEXS-1.004000
    echo "+ Installing $JSON_MAYBEXS"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/H/HA/HAARG/$JSON_MAYBEXS_VER.tar.gz
    tar -xvzf $JSON_MAYBEXS_VER.tar.gz

    cd $JSON_MAYBEXS_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$JSON_MAYBEXS
    make
    make install
    cp $TEMP_DIR/$JSON_MAYBEXS/lib/perl5/site_perl/JSON/MaybeXS.pm $CPAN_DIR/JSON/.

    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/JSON/MaybeXS.pm already exists, not installing"
fi


# 3 https://metacpan.org/pod/Log::Log4perl

if [ ! -d "$CPAN_DIR/Log/Log4perl" ]; then
    LOG4PERL=Log-Log4perl
    LOG4PERL_VER=$LOG4PERL-1.49
    echo "+ Installing $LOG4PERL"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/M/MS/MSCHILLI/$LOG4PERL_VER.tar.gz
    tar -xvzf $LOG4PERL_VER.tar.gz

    cd $LOG4PERL_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$LOG4PERL
    make
    make install
    cp -r $TEMP_DIR/$LOG4PERL/lib/perl5/site_perl/Log $CPAN_DIR/.

    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/Log/Log4Perl already exists, not installing"
fi

# 4 https://metacpan.org/pod/HTTP::Tiny

if [ ! -f "$CPAN_DIR/HTTP/Tiny.pm" ]; then
    HTTP_TINY=HTTP-Tiny
    HTTP_TINY_VER=$HTTP_TINY-0.076
    echo "+ Installing $HTTP_TINY"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/D/DA/DAGOLDEN/$HTTP_TINY_VER.tar.gz
    tar -xvzf $HTTP_TINY_VER.tar.gz

    cd $HTTP_TINY_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$HTTP_TINY
    make
    make install

    cp -r $TEMP_DIR/$HTTP_TINY/lib/perl5/site_perl/HTTP/* $CPAN_DIR/HTTP/.

    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/$HTTP_TINY already exists, not installing"
fi


# 5 https://metacpan.org/pod/Module::Load

if [ ! -d "$CPAN_DIR/Module" ]; then
    MODULE_LOAD=Module-Load
    MODULE_LOAD_VER=$MODULE_LOAD-0.32
    echo "+ Installing $MODULE_LOAD"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/B/BI/BINGOS/$MODULE_LOAD_VER.tar.gz
    tar -xvzf $MODULE_LOAD_VER.tar.gz

    cd $MODULE_LOAD_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$MODULE_LOAD
    make
    make install
    cp -r $TEMP_DIR/$MODULE_LOAD/lib/perl5/site_perl/Module $CPAN_DIR/.

    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/$MODULE_LOAD already exists, not installing"
fi


# 6 https://metacpan.org/pod/Time::Piece

if [ ! -f "$CPAN_DIR/$PERL_FOLDER/Time/Piece.pm" ]; then
    TIME_PIECE=Time-Piece
    TIME_PIECE_VER=$TIME_PIECE-1.33
    echo "+ Installing $TIME_PIECE"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/E/ES/ESAYM/$TIME_PIECE_VER.tar.gz
    tar -xvzf $TIME_PIECE_VER.tar.gz

    cd $TIME_PIECE_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$TIME_PIECE
    make
    make install

    #cp -r $TEMP_DIR/$TIME_PIECE/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/Time $CPAN_DIR/.
    cp -r $TEMP_DIR/$TIME_PIECE/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/Time $CPAN_DIR/$PERL_FOLDER
    cp -r $TEMP_DIR/$TIME_PIECE/lib/perl5/site_perl/5.18.2/darwin-thread-multi-2level/auto/Time $CPAN_DIR/$PERL_FOLDER/auto/.

    cd $TEMP_DIR
else
    echo "*** $CPAN_DIR/$TIME_PIECE already exists, not installing"
fi



# FINALLY, compile up Crypt::LE
# https://metacpan.org/pod/Crypt::LE

if [ ! -d "$CPAN_DIR/Crypt/LE" ]; then
    CRYPT_LE=Crypt-LE
    CRYPT_LE_VER=$CRYPT_LE-0.31
    echo "+ FINALLY, Installing $CRYPT_LE"
    wget $WGET_FLAGS https://cpan.metacpan.org/authors/id/L/LE/LEADER/$CRYPT_LE_VER.tar.gz
    tar -xvzf $CRYPT_LE_VER.tar.gz

    cd $CRYPT_LE_VER
    perl Makefile.PL PREFIX=$TEMP_DIR/$CRYPT_LE
    make
    make install

    cp -r $TEMP_DIR/$CRYPT_LE/lib/perl5/site_perl/Crypt/* $CPAN_DIR/Crypt/.
    # the most important step: we need the le.pl binary
    cp -r $TEMP_DIR/$CRYPT_LE/bin $CPAN_DIR/Crypt/LE/.

    cd $CPAN_DIR
else
    echo "*** $CPAN_DIR/$CRYPT_LE already exists, not installing"
fi


# DONE

echo "*****************************"
echo "*** Done compiling Crypt::LE."
if [ "x$1" != "x--keep" ] ; then
    echo "    Will now delete tmp subdir"
    rm -rf tmp
else
    echo "   Not deleting the $TEMP_DIR"
fi

# restore env vars
C_INCLUDE_PATH=$OLD_C_INCLUDE_PATH
PERL5LIB=$OLD_PERL5LIB

# for this export line to work, would need to source ./compile-zerossl.sh
#export PERL5LIB=$CPAN_DIR:$CPAN_DIR/$PERL_FOLDER:$PERL5LIB

echo "Restored environment"
echo "You can now run $CPAN_DIR/Crypt/LE/bin/le.pl after exporting PERL5LIB to contain both cpan and cpan/$PERL_FOLDER. Do:"
echo "   export PERL5LIB=$CPAN_DIR:$CPAN_DIR/$PERL_FOLDER:$PERL5LIB"
