#!/bin/bash
###
# @Author       : lqm283
# @Date         : 2024-06-27 08:48:46
 # @LastEditTime : 2025-09-10 08:33:19
 # @LastEditors  : lqm283
# --------------------------------------------------------------------------------<
# @Description  : Please edit a descrition about this file at here.
# --------------------------------------------------------------------------------<
###

zephyr_depenance="git cmake ninja-build gperf \
  ccache dfu-util device-tree-compiler wget \
  python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \
  make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 protobuf-c-compiler  \
  protobuf-compiler libprotobuf-c-dev python3-venv pv"

dependance="git curl pkg-config libsdl2-dev:i386 xmlstarlet\
  python-is-python3 python3-pyelftools iputils-ping picocom"

url=ssh://git@gitlab.veryark.cn:3399/developer/pump/pump-manifest.git
branch=""
manifest=""

local_server=192.168.10.10
veryark_server=script.veryark.cn
repo_url=https://mirrors.tuna.tsinghua.edu.cn/git/git-repo
local_bin=~/.local/bin

sdk_version="0.16.8"

WORKSPACE=$(pwd)
script_file=$0
PASSWORD=""
os_version=0
os_minversion=22.04

function get_option() {
    while getopts ":u:b:m:" opt; do
        case $opt in
        u)
            url=$OPTARG
            ;;
        b)
            branch=$OPTARG
            ;;
        m)
            manifest=$OPTARG
            ;;
        \?)
            echo "Invalid option: -$OPTARG" >&2
            exit 1
            ;;
        :)
            echo "Option -$OPTARG requires an argument." >&2
            exit 1
            ;;
        esac
    done

    if [ -z "$branch" ] || [ -z "$manifest" ]; then
        echo "Error: Both -b and -m options are required."
        echo "Usage: \$0 -b value1 -m value2"
        exit 1
    fi
}

function _check_git() {
    if [[ $(git config user.name) == "" ]]; then
        read -p "plase input your git username: " uasename
        git config --global user.name "$uasename"
    fi

    if [[ $(git config user.email) == "" ]]; then
        read -p "plase input your git email: " email
        git config --global user.email "$email"
    fi
}

function _install_kit_ware() {
    local kitware_url="https://apt.kitware.com/kitware-archive.sh"
    os_version=$(lsb_release -r --short)
    os_version=$(echo "$os_version" | bc)
    if awk "BEGIN {exit !($os_version < $os_minversion)}"; then
        # add the Kitware APT repository
        echo "install kitware."
        wget https://apt.kitware.com/kitware-archive.sh
        sudo bash kitware-archive.sh
        rm kitware-archive.sh
    fi
}

function _add_sdl2_surports() {
    if [ -e "/lib/i386-linux-gnu/libSDL2-2.0.so" ]; then
        echo "sdl2 installed."
        return 0
    else
        sudo dpkg --add-architecture i386
        echo "export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig" >>~/.bashrc
    fi
}

function _update_sys() {
    export DEBIAN_FRONTEND=noninteractive
    sudo apt update -y
    sudo apt install --no-install-recommends $dependance $zephyr_depenance -y
    sudo apt upgrade -y
    sudo apt upgrade --fix-broken -y
}

function _setting_pip_source() {
    mkdir -p ~/.pip
    if [ -e "$HOME/.pip/pip.conf" ]; then
        return 0
    fi
    local str="[global]\n
                timeout = 6000\n
                index-url = http://mirrors.aliyun.com/pypi/simple/\n
                [install]\n
                trusted-host=mirrors.aliyun.com\n"
    echo -e $str >~/.pip/pip.conf
    if awk "BEGIN {exit !($os_version < 22.04)}"; then
        pip install --upgrade zipp pyyaml six click jinja2
    fi
}

function flush_passwd() {
    export SUDO_PASSWORD=$PASSWORD
    sudo -k
    sudo -S -v <<<"$SUDO_PASSWORD"
}

function env_init() {
    echo -n "Enter your user password: "
    read -s PASSWORD
    flush_passwd
    sudo apt update
    if ! type bc >/dev/null 2>&1; then
        sudo apt install bc
    fi
    if ! type dialog >/dev/null 2>&1; then
        sudo apt install dialog
    fi
    if type git >/dev/null 2>&1; then
        _check_git
    fi
    _install_kit_ware
    _add_sdl2_surports
    _update_sys
    _check_git
    _setting_pip_source
}

function repo_init() {
    local repo_local_url="https://$veryark_server/sdk/repo"

    local url=""
    check_ip_status $veryark_server
    if [ $? == 0 ]; then
        url=$repo_local_url
    else
        url=$repo_url
    fi

    mkdir -p $local_bin
    if ! [ -e "$local_bin/repo" ]; then
        curl --progress-bar -k $url >$local_bin/repo
    fi
    chmod +x $local_bin/repo
    export REPO_URL=$repo_url
    if [[ $(echo $PATH | grep ~/.local/bin) == "" ]]; then
        echo "add $local_bin into PATH"
        echo 'export PATH=~/.local/bin:$PATH' >>~/.bashrc
        echo "export REPO_URL='${repo_url}'" >>~/.bashrc
        export PATH="$local_bin:$PATH"
    fi
}

function repo_sync() {
    echo "repo init -u $url -b $branch -m $manifest"
    yes "y" | GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new" repo init -u $url -b $branch -m $manifest
    if [ $? -ne 0 ]; then
        echo "repo init failed,please try again!"
        exit 1
    fi
    echo "repo sync"
    if echo $manifest | grep -q "rel"; then
        echo "Now sync to release."
        export GIT_DEPTH="1"
    fi
    echo 'y' | repo sync
    if [ $? -ne 0 ]; then
        echo "repo sync failed,please try again!"
        exit 1
    fi
}

function set_branch() {
    if echo $manifest | grep -q "rel"; then
        echo "manifests file is $manifest"
        return 0
    fi
    local current_path=$(pwd)
    local l_manifest="$current_path/.repo/manifests/$manifest"
    while IFS= read -r line; do
        local name=$(echo "$line" | cut -d' ' -f1)
        local revision=$(echo "$line" | cut -d' ' -f2)
        repo start $revision $name
    done < <(xmlstarlet sel -t -m "//project" -v "@name" -o " " -v "@revision" -n $l_manifest)
}

function check_ip_status() {
    ping -c 3 -i 0.2 -W 3 $1 &>/dev/null
    if [ $? -eq 0 ]; then
        return 0
    else
        return -1
    fi
}

function _install_sdk() {
    local sdk_file_name="zephyr-sdk-${sdk_version}_linux-x86_64.tar.xz"
    local sdk_local_url="http://$local_server/${sdk_file_name}"
    local sdk_remote_url="https://$veryark_server/sdk/${sdk_file_name}"

    # Check if SDK is already installed
    if [ -d "${local_bin}/zephyr-sdk-${sdk_version}" ]; then
        # Additional check to verify if setup is complete
        if [ -f "${local_bin}/zephyr-sdk-${sdk_version}/setup.sh" ] && \
           [ -d "${local_bin}/zephyr-sdk-${sdk_version}/sysroots" ]; then
            echo "zephyr-sdk-${sdk_version} is already installed and configured."
            return 0
        else
            echo "zephyr-sdk-${sdk_version} directory exists but appears to be incomplete or corrupted."
            echo "Reinstalling the SDK..."
        fi
    else
        echo "Installing zephyr-sdk-${sdk_version}..."
    fi

    temp_dir=".sdktemp"
    url=""
    check_ip_status $local_server
    if [ $? == 0 ]; then
        url=$sdk_local_url
    else
        url=$sdk_remote_url
    fi
    mkdir -p $temp_dir
    echo "url = ${url}"
    curl --progress-bar -k $url >$temp_dir/$sdk_file_name
    rm -rf ${local_bin}/zephyr-sdk-*
    mkdir -p ${local_bin}
    local expanded_path=$(eval echo ${local_bin}/${ui_sdk_version}/${sdk_source})
    pv ${temp_dir}/${sdk_file_name} | tar xJf - -C $expanded_path
    if [ $? -ne 0 ]; then
        echo "uncompression ${temp_dir}/${sdk_file_name} failed!"
        rm -rf $temp_dir
        exit 1
    fi
    rm -rf $temp_dir
    yes "y" | bash $local_bin/zephyr-sdk-$sdk_version/setup.sh
    sudo cp ${local_bin}/zephyr-sdk-${sdk_version}/sysroots/x86_64-pokysdk-linux/usr/share/openocd/contrib/60-openocd.rules /etc/udev/rules.d
    sudo udevadm control --reload
}

function _install_west() {
    python3 -m venv .venv
    source .venv/bin/activate
    pip3 install west
}

function zephyr_update() {
    current_path=$(pwd)
    mkdir -p .west
    echo -e "[manifest]\npath = zephyr\nfile = west.yml\n" >.west/config
    west config manifest.project-filter -- +nanopb
    west update
    west zephyr-export
    pip3 install -r $current_path/bootloader/boot/scripts/requirements.txt
    west packages pip --install
    pip3 install protobuf grpcio-tools
}

function echo_debug_conf() {
    if echo $manifest | grep -q "rel"; then
        echo "manifests file is $manifest"
        return 0
    fi
    current_path=$(pwd)
    if [ -d "$current_path/ui" ]; then
        echo "Creating empty debug.conf in $current_path/ui directory"
        cat > "$current_path/ui/debug.conf" << EOF
# Debug configuration file
# Created automatically by project init script

#系统功能
## 控制台
CONFIG_CONSOLE=y
## UART 控制台
CONFIG_UART_CONSOLE=y
## tftp
CONFIG_TFTP_LIB=y

# 优化等级
## O0优化
# CONFIG_NO_OPTIMIZATIONS=y
## Os优化
# CONFIG_SIZE_OPTIMIZATIONS=y
## Oz优化
# CONFIG_SIZE_OPTIMIZATIONS_AGGRESSIVE=y
## O2优化
# CONFIG_SPEED_OPTIMIZATIONS=y
## O3优化
# CONFIG_HIGH_SPEED_OPTIMIZATIONS=y
## Ofast优化
CONFIG_FAST_OPTIMIZATIONS=y
## Og优化
# CONFIG_DEBUG_OPTIMIZATIONS=y

# 调试相关的配置
## 日志
CONFIG_LOG=y # 日志支持
## 线程调试
### 线程分析器
CONFIG_THREAD_ANALYZER=y
### 使用 printk 输出分析信息
# CONFIG_THREAD_ANALYZER_USE_PRINTK=y
### 自动分析
# CONFIG_THREAD_ANALYZER_AUTO=y
### 自动分析间隔
# CONFIG_THREAD_ANALYZER_AUTO_INTERVAL=10
CONFIG_THREAD_NAME=y # 线程名称支持
### 打印线程栈信息
CONFIG_THREAD_STACK_INFO=y
### 打印线程运行时统计信息
CONFIG_THREAD_RUNTIME_STATS=y
### 使用时间函数来收集统计信息
CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y

# shell
## Shell 支持
CONFIG_SHELL=y
## Shell 提示符缓冲区大小
CONFIG_SHELL_PROMPT_BUFF_SIZE=40
## Shell 线程的栈大小
CONFIG_SHELL_STACK_SIZE=32768
## winstream 控制台缓冲区的大小（以字节为单位）
CONFIG_WINSTREAM_CONSOLE_STATIC_SIZE=65536
## shell printf 缓冲区大小
CONFIG_SHELL_PRINTF_BUFF_SIZE=32768


# Add additional debug configurations as needed
EOF
        echo "debug.conf file created successfully"
    else
        echo "ui directory not found, skipping debug.conf creation"
    fi
}

function zephyr_init() {
    _install_sdk
    _install_west
}

# 定义一个函数来执行清理操作
function cleanup() {
    exit -1
}

function __exit() {
    cd $WORKSPACE
    rm $WORKSPACE/$script_file
}

function trap_exit() {
    trap __exit EXIT
    trap cleanup SIGINT
}

function mkdir_project() {
    if [ -n "${PROJECT_DIR}" ]; then
        projectname=$(basename "${PROJECT_DIR}")
        echo "Using project directory from environment: ${PROJECT_DIR}"
        mkdir -p $WORKSPACE/$PROJECT_DIR
        cd $WORKSPACE/$PROJECT_DIR
    else
        read -p "plase input your project name: " projectname
        mkdir -p $WORKSPACE/$projectname
        cd $WORKSPACE/$projectname
    fi
}

trap_exit
get_option "$@"
mkdir_project
env_init
repo_init
repo_sync
echo_debug_conf
set_branch
flush_passwd
zephyr_init
zephyr_update

echo "Project $projectname init all done!!"
echo 'Now please use command "source ~/.bashrc" to reload the bash configuration.'
