#!/usr/bin/env bash
#
# A build-and-installer script for including SL-LIN support in Linux kernels
#
# @copyright Highly Confidential and Proprietary Zoox Information. Copyright (c) Zoox
#
# Author: trawat
# Date Created: February 18, 2020
#
# Note: this script relies on the presence and accessibility of the script to
#       https://git.zooxlabs.com/zooxco/linux-lin. If this script fails for
#       reasons of inaccessibility, request and obtain access and rerun it.
#
#       Git must also be installed.
#
#       And gcc.

# Set script runtime options
LOG_DIR="$HOME/sllin_logs"
LOG="$LOG_DIR/build_sllin.txt"
mkdir -p $LOG_DIR
echo "\n\n" > $LOG
date>>$LOG

# Set repo name in variable
LIN_REPO_NAME="linux-lin"
CAN_REPO_NAME="can-utils"
ATTACH_PATH="$HOME/zoox/driving/firmware/validation/tools"

# Find lin buses
# This assumes the udev rules have been applied so ttyUSBs can be accessed with symlinks.
R="/dev/LIN*"
LIN_BUSES=$(ls ${R})
echo "Found the following lin buses: ${LIN_BUSES}">>$LOG

# Save where we are cuz it makes life easier later
TOP_LEVEL=`pwd`

# Check given CLI parameters and set variables if not given
# ${1} - insert - if 'bind' then insert kernel module and if 'skip' then only build
# ${2} - master - if 'master' then setup sllin as master node, else slave
if [ -z "$1" ]; then
    insert="bind"
else
    insert="skip"
fi

echo "Prepping linux-lin">>$LOG
# If the repository doesn't exist, try to clone it
if [ ! -d "${LIN_REPO_NAME}" ]; then
    git clone git@git.zooxlabs.com:zooxco/linux-lin.git ${LIN_REPO_NAME} > /dev/null 2>&1
fi

# Change to the repo directory
cd ${LIN_REPO_NAME}

# use master or slave branch depending on arguments passed.
if [ "$2" == "master" ]; then
    git checkout master > /dev/null 2>&1>>$LOG
else
    git checkout master > /dev/null 2>&1>>$LOG
    git pull
    git checkout user/skapre/sllin_slave > /dev/null 2>&1>>$LOG
fi

# Compile the project
echo "Building linux-lin">>$LOG
cd sllin
make > /dev/null 2>&1

# Insert the module into the kernel space
if [ $insert=="bind" ]; then
    sudo rmmod ./sllin.ko > /dev/null 2>&1
    if [ "$2" == "master" ]; then
        echo "Inserting sllin.ko as master">>$LOG
        sudo insmod ./sllin.ko
    else
        echo "Inserting sllin.ko as slave">>$LOG
        sudo insmod ./sllin.ko master=0
    fi
fi

# Now we need to grab cantools...
echo "Prepping cantools">>$LOG
cd ${TOP_LEVEL}
if [ ! -d "${CAN_REPO_NAME}" ]; then
    git clone --depth=1 https://github.com/linux-can/can-utils.git ${CAN_REPO_NAME} > /dev/null 2>&1
fi

# Change into the cantools directory
cd ${CAN_REPO_NAME}

# Change to master branch
git checkout master > /dev/null 2>&1

# Patch SL-CAN for use in/as SL-LIN
echo "Patching slcan_attach.c">>$LOG
sed -i 's/N_SLCAN/25/g' slcan_attach.c

# Now make slcan_attach
echo "Building slcan_attach">>$LOG
make slcan_attach > /dev/null 2>&1

# Rename slcan to sllin
echo "Renaming slcan_attach -> sllin_attach">>$LOG
mv slcan_attach sllin_attach

cd ${ATTACH_PATH}
sudo chmod +x attach_sllin.sh

# Bind device to SL-LIN and bring up interface
if [ "$insert" == "bind" ]; then
    for lin_bus in ${LIN_BUSES[@]}; do
        v=${lin_bus:5}
        screen -dm -S "${v}" ./attach_sllin.sh ${lin_bus}
        sleep 5
        sudo ip link set "${v}" up
    done
fi
# Clean up repositories
if [ "$insert" == "skip" ]; then
    echo "Skipping cleanup. Built files should be in their respective repos.">>$LOG
else
    echo "Cleaning up..."
    cd ${TOP_LEVEL}
    rm -rf ${LIN_REPO_NAME}
    rm -rf ${CAN_REPO_NAME}
fi
echo "Done">>$LOG
