#!/bin/bash

# This is the build script that can be executed within a Lambda build Docker container.
# Usage from host OS:
#
# docker run -it \
# --volume <repo home>:/reporoot <Lambda image> \
# /home/jenkins/build.sh \
# <environment> \
# /reporoot/<path to Lambda root in repo> \
# <Lambda dir name>
#
# This script and the Docker process will exit with code 0 upon successful installation
# of dependencies, packaging of function, and execution of unit tests.

export ENVIRONMENT="$1"
export LAMBDA_HOME="$2"
export FUNC_NAME="$3"
export SKIP_TESTS="$4"
export BUILD_HOME="/home/jenkins"

# possible versions "2.7" and "3.6"
export PYTHON_VERSION="2.7"

if [ -z "$ENVIRONMENT" -o -z "$LAMBDA_HOME" -o -z "$FUNC_NAME" ]
then
    echo "Please provide environment, lambda home dir, and function name" >&2
    exit 1
fi

export VIRT_NAME="virt_$FUNC_NAME"
export TEST_VIRT_NAME="test_virt_$FUNC_NAME"
export VIRT_HOME="$BUILD_HOME/$VIRT_NAME"
export TEST_VIRT_HOME="$BUILD_HOME/$TEST_VIRT_NAME"
export DEPLOY_ZIP="$LAMBDA_HOME/$FUNC_NAME/deploy.zip"

rm -rf "./$VIRT_NAME"
cd "$BUILD_HOME" || exit 1

if [ $PYTHON_VERSION = "3.6" ]
then
    export VENV_COMMAND="python3 -m venv"
else
    export VENV_COMMAND="virtualenv"
fi

$VENV_COMMAND "$VIRT_NAME"

source "$VIRT_HOME/bin/activate"
cd "$VIRT_HOME" || exit 1
pip install -r "$LAMBDA_HOME/$FUNC_NAME/requirements.txt"
deactivate

# Fix Google Protobuf issue for Lambda
if [ -e "$VIRT_HOME/lib/python$PYTHON_VERSION/site-packages/google" ]
then
    echo "Fixing google protobuf package issue"
    touch "$VIRT_HOME/lib/python$PYTHON_VERSION/site-packages/google/__init__.py"
fi

# Fix Snowflake import issue for Lambda
if [ -e "$VIRT_HOME/lib/python$PYTHON_VERSION/site-packages/snowflake" ]
then
    echo "Fixing snowflake package issue"
    touch "$VIRT_HOME/lib/python$PYTHON_VERSION/site-packages/snowflake/__init__.py"
fi

# Clean up previous deploy file if existed.
rm "$DEPLOY_ZIP"

# Zip up dependencies.
cd "$VIRT_HOME" || exit 1
cd "$VIRT_HOME/lib/python$PYTHON_VERSION/site-packages" || exit 1
zip -r9 "$DEPLOY_ZIP" .

# And x64 libs also.
cd "$VIRT_HOME/lib64/python$PYTHON_VERSION/site-packages" || exit 1
zip -r9 "$DEPLOY_ZIP" .

# If available, zip up shared Lambda modules.
if [ -e "$LAMBDA_HOME/common" ]
then
    export PYTHONPATH="$PYTHONPATH:$LAMBDA_HOME/common"
    cd "$LAMBDA_HOME/common" || exit 1
    find . -name '*.py' | xargs zip "$DEPLOY_ZIP"
fi

# Zip up Lambda function itself.
cd "$LAMBDA_HOME/$FUNC_NAME" || exit 1
find . -name '*.py' | xargs zip "$DEPLOY_ZIP"

# Now we run tests (or skip).
if [ $SKIP_TESTS = "skiptests" ]
then
    echo "Skipping the tests. Done."
    exit 1
fi

source "$VIRT_HOME/bin/activate"

if [ -e "$LAMBDA_HOME/common" ]
then
    cd "$LAMBDA_HOME/common"

    if [ -f "$LAMBDA_HOME/common/requirements.txt" ]
    then
        pip install -r "$LAMBDA_HOME/common/requirements.txt"
    fi

    pip install -r "$LAMBDA_HOME/common/requirements-dev.txt"
    python -m pytest tests/
    TEST_COMMON_EXIT_CODE="$?"
    # We need to ignore import order, because flake8 treats modules imported from
    # 'common' as external packages.
    flake8 --ignore=I100
    LINT_COMMON_EXIT_CODE="$?"
fi
cd "$LAMBDA_HOME/$FUNC_NAME" || exit 1
pip install -r "$LAMBDA_HOME/$FUNC_NAME/requirements-dev.txt"

python -m pytest tests/
TEST_EXIT_CODE="$?"
cd "$LAMBDA_HOME/$FUNC_NAME" || exit 1
# We need to ignore import order, because flake8 treats modules imported from
# 'common' as external packages.
flake8 --ignore=I100
LINT_EXIT_CODE="$?"
deactivate
exit $[ $TEST_COMMON_EXIT_CODE + $LINT_COMMON_EXIT_CODE + $TEST_EXIT_CODE + $LINT_EXIT_CODE ]
