#!/bin/bash
# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -e
set +e
echo -e "\n\033[32m\t*********Welcome to sharekit thirdparty!*********\033[0m\n"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

ROOT_DIR=$(pwd)
ROOT_INSTALL=${ROOT_DIR}/lib_install
ROOT_OUTPUT=${ROOT_DIR}/out
#TARGET_ARCH=aarch64-linux-gnu
TARGET_ARCH=x86_64-linux-gnu

usage() {
    cat << EOF
    Sharekit third party 交叉编译脚本

    用法: $0 [选项]

    选项:
    --target=x86-64-linux-gnu         
                           支持: x86-64-linux-gun(默认),aarch64-linux-gnu, arm-linux-gnueabihf,
                                arm-linux-gnueabi, etc
    --clean                清理编译文件
    --help                 显示此帮助信息


    示例:
    # 交叉编译 AArch64 三方库
    $0 --target=aarch64-linux-gnu

    # 交叉编译 ARM 三方库
    $0 --target=arm-linux-gnueabihf

    
    # 删除三方库
    $0 --clean
EOF
}

clean_build() {
    echo "=== 清理编译文件 ==="
    rm -rf ${ROOT_OUTPUT}
    rm -rf ${ROOT_INSTALL}
    echo "=== 清理完成 ==="
}

check_command_line() {
    while [ $# -gt 0 ]; do
        case $1 in
            --target=*)
                TARGET_ARCH="${1#*=}"
                ;;
            --clean)
                clean_build
                exit 0
                ;;
            --help)
                usage
                exit 0
                ;;
            *)
                echo "错误: 未知选项 $1"
                usage
                exit 1
                ;;
        esac
        shift
    done
}

check_command_line "$@"

if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/x86_64
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/x86_64
elif [[ "$TARGET_ARCH" == "aarch64-linux-gnu" ]]; then
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/aarch64
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/aarch64
elif [[ "$TARGET_ARCH" == "arm-linux-gnueabihf" ]]; then
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/arm
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/arm
else
    ROOT_ARCH_OUTPUT=${ROOT_OUTPUT}/aarch64
    ROOT_ARCH_INSTALL=${ROOT_INSTALL}/aarch64
fi

function check_shell_environment() {
  case $(uname -s) in 
    Linux)
          shell_result=$(/bin/sh -c 'echo ${BASH_VERSION}')
          if [ -n "${shell_result}" ]; then
            echo -e "\033[32mSystem shell: bash ${shell_result}\033[0m"
          else
            echo -e "\033[33m Your system shell isn't bash, we recommend you to use bash, because some commands may not be supported in other shells, such as pushd and shopt are not supported in dash. \n You can follow these tips to modify the system shell to bash on Ubuntu: \033[0m"
            echo -e "\033[33m [1]:Open the Terminal tool and execute the following command: sudo dpkg-reconfigure dash \n [2]:Enter the password and select <no>  \033[0m"
          fi
          ;;
    Darwin)
          echo -e "\033[31m[OHOS ERROR] Darwin system is not supported yet\033[0m"
          ;;
    *)
          echo -e "\033[31m[OHOS ERROR] Unsupported this system: $(uname -s)\033[0m"
          exit 1
  esac
}

check_shell_environment

echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32mCurrent time: $(date +%F' '%H:%M:%S)\033[0m"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32mBuild args: $@\033[0m"
echo -e "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

# 设置工具链
setup_toolchain() {
    echo "============ 检查交叉编译工具链 =============="
    if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
        export CC=gcc
        export CXX=g++
        export AR=ar
        export RANLIB=ranlib
        export LD=ld
        export STRIP=strip
    else
        export CC=/usr/bin/${TARGET_ARCH}-gcc
        export CXX=/usr/bin/${TARGET_ARCH}-g++
        export AR=/usr/bin/${TARGET_ARCH}-ar
        export RANLIB=/usr/bin/${TARGET_ARCH}-ranlib
        export LD=/usr/bin/${TARGET_ARCH}-ld
        export STRIP=/usr/bin/${TARGET_ARCH}-strip
    fi
}
setup_toolchain

# 检查交叉编译工具链
check_toolchain() {
    echo "============ 检查交叉编译工具链 =============="
    if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
        # 检查本地工具链
        if ! command -v gcc &> /dev/null; then
            echo "错误: gcc 未找到"
            echo "请安装本地编译工具链:"
            echo "  Ubuntu/Debian: sudo apt install build-essential"
            echo "  CentOS/RHEL: sudo yum groupinstall 'Development Tools'"
            exit 1
        fi
        echo "本地工具链检查通过: $(gcc --version | head -n1)"
    else
        # 交叉编译工具链检查保持不变
        if ! command -v ${CC} &> /dev/null; then
            echo "错误: 交叉编译工具链 ${TARGET_ARCH} 未找到"
            echo "请安装对应的工具链:"
            echo "  Ubuntu/Debian: sudo apt install gcc-${TARGET_ARCH} g++-${TARGET_ARCH}"
            echo "  CentOS/RHEL: sudo yum install gcc-${TARGET_ARCH}-linux-gnu"
            exit 1
        fi
        echo "工具链检查通过: $(${CC} --version | head -n1)"
    fi
}
check_toolchain

compile_expat() {
    echo "============ 编译 expat ============"
    if [[ ! -d "${ROOT_ARCH_OUTPUT}/expat-2.5.0" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/expat-2.5.0.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/expat-2.5.0

    ./buildconf.sh
    
    # 修改configure调用
    if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
        ./configure --prefix=$ROOT_ARCH_INSTALL
    else
        ./configure --host=${TARGET_ARCH} --prefix=$ROOT_ARCH_INSTALL
    fi
    
    make -j$(nproc) && make install
    
    if [[ "$?" -ne 0 ]]; then
        echo -e "\033[31m=====build expat error=====\033[0m"
        exit 1
    fi
}

compile_dbus() {
    echo "============ 编译 dbus ============"
    if [[ ! -d "${ROOT_ARCH_OUTPUT}/dbus-1.15.0" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/dbus-1.15.0.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/dbus-1.15.0

    if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
        ./configure --prefix=$ROOT_ARCH_INSTALL LDFLAGS=-L$ROOT_ARCH_INSTALL/lib \
        --disable-selinux --enable-tests=no --without-x
    else
        ./configure --host=${TARGET_ARCH} --prefix=$ROOT_ARCH_INSTALL LDFLAGS=-L$ROOT_ARCH_INSTALL/lib \
        --disable-selinux --enable-tests=no --without-x
    fi
    
    make -j$(nproc) && make install
    
    if [[ "$?" -ne 0 ]]; then
        echo -e "\033[31m=====build dbus error=====\033[0m"
        exit 1
    fi
}

compile_ncurses() {
    echo "============ 编译 ncurses ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/ncurses-6.3" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/ncurses-6.3.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/ncurses-6.3

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL --with-shared --without-debug --disable-stripping

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_readline() {
    echo "============ 编译 readline ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/readline-8.2" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/readline-8.2.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/readline-8.2

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL LDFLAGS=-L$ROOT_ARCH_INSTALL/lib --with-shared

    make SHLIB_LIBS="-L$ROOT_ARCH_INSTALL/lib -lncurses" -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libffi() {
    echo "============ 编译 libffi ============"
    if [[ ! -d "${ROOT_ARCH_OUTPUT}/libffi-3.2.1" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libffi-3.2.1.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libffi-3.2.1

    ./autogen.sh
    
    if [[ "$TARGET_ARCH" == "x86_64-linux-gnu" ]]; then
        ./configure --prefix=$ROOT_ARCH_INSTALL
    else
        ./configure --host=${TARGET_ARCH} --prefix=$ROOT_ARCH_INSTALL
    fi
    
    make -j$(nproc) && make install
    
    if [[ "$?" -ne 0 ]]; then
        echo -e "\033[31m=====build libffi error=====\033[0m"
        exit 1
    fi
}

compile_zlib() {
    echo "============ 编译 zlib ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/zlib-1.2.13" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/zlib-1.2.13.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/zlib-1.2.13

    ./configure --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libiconv() {
    echo "============ 编译 libiconv ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/libiconv-1.16" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libiconv-1.16.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libiconv-1.16

    ./configure --host=arm-linux --prefix=$ROOT_ARCH_INSTALL 

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_gettext() {
    echo "============ 编译 gettext ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/gettext-0.20" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/gettext-0.20.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/gettext-0.20

    ./configure --host=arm-linux --prefix=$ROOT_ARCH_INSTALL 

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_glib() {
    echo "============ 编译 glib ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/glib-2.58.3" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/glib-2.58.3.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/glib-2.58.3

    ./autogen.sh 
    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL CFLAGS="-fPIC -I$ROOT_ARCH_INSTALL/include" LDFLAGS=-L$ROOT_ARCH_INSTALL/lib \
    PKG_CONFIG_PATH=$ROOT_ARCH_INSTALL/lib/pkgconfig \
    LIBFFI_CFLAGS="-I$ROOT_ARCH_INSTALL/include -I$ROOT_ARCH_INSTALL/lib/libffi-3.2.1/include" \
    LIBFFI_LIBS="-L$ROOT_ARCH_INSTALL/lib -lffi" \
    ZLIB_CFLAGS="-I$ROOT_ARCH_INSTALL/include" \
    ZLIB_LIBS="-L$ROOT_ARCH_INSTALL/lib -lz" \
    --with-pcre=internal \
    --with-libiconv=gnu \
    glib_cv_stack_grows=no \
    glib_cv_have_qsort_r=yes \
    glib_cv_long_long_format=ll \
    glib_cv_uscore=no \
    glib_cv_have_strlcpy=no \
    glib_cv_va_val_copy=yes \
    glib_cv_rtldglobal_broken=no \
    ac_cv_func_posix_getpwuid_r=yes \
    ac_cv_func_posix_getgrgid_r=yes \
    ac_cv_func_printf_unix98=yes \
    ac_cv_func_vsnprintf_c99=yes \
    ac_cv_func_snprintf_c99=yes \
    ac_cv_func_nl_langinfo=yes \
    ac_cv_func_getpwuid_r=yes \
    ac_cv_func_getgrgid_r=yes \
    ac_cv_func_fallocate=yes \
    --enable-shared \
    --disable-static \
    --disable-dependency-tracking \
    --with-pcre=internal \
    --disable-libmount \
    --disable-selinux \
    --disable-xattr \
    --disable-dtrace \
    --disable-systemtap \
    --disable-gtk-doc \
    --disable-libelf \
    --disable-tests

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_bluez() {
    echo "============ 编译 bluez ============"
    if [[ ! -f "${ROOT_ARCH_OUTPUT}/bluez-5.63" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/bluez-5.63.tar.xz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/bluez-5.63

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL \
    CFLAGS="-fPIC -I$ROOT_ARCH_INSTALL/include -I$ROOT_ARCH_INSTALL/include/glib-2.0 -I$ROOT_ARCH_INSTALL/include/dbus-1.0 " \
    LDFLAGS="-L$ROOT_ARCH_INSTALL/lib -lncurses -lreadline -ldbus-1 -lglib-2.0" \
    PKG_CONFIG_PATH=$ROOT_ARCH_INSTALL/lib/pkgconfig \
    --disable-udev \
    --disable-obex \
    --enable-library \
    --enable-experimental \
    --enable-deprecated \
    --with-dbusconfdir=$ROOT_ARCH_INSTALL/etc

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

compile_libnl() {
    echo "============ 编译 libnl ============"
    if [[ ! -f "${ROOT_DIR}/third_party/libnl-3.2.28" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/libnl-3.2.28.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/libnl-3.2.28

    ./configure --host=arm-linux --target=arm-linux --prefix=$ROOT_ARCH_INSTALL

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

export CFLAGS="-I$ROOT_ARCH_INSTALL/include"
export LDFLAGS="-L$ROOT_ARCH_INSTALL/lib"

compile_openssl() {
    echo "============ 编译 gettext ============"
    if [[ ! -d "${ROOT_ARCH_OUTPUT}/openssl-1.1.1c" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/openssl-1.1.1c.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/openssl-1.1.1c

    # 根据架构选择不同的配置
    case "${TARGET_ARCH}" in
        x86_64-linux-gnu)
            ./config --prefix=$ROOT_ARCH_INSTALL shared
            ;;
        aarch64-linux-gnu)
            ./Configure --prefix=$ROOT_ARCH_INSTALL linux-aarch64 shared
            ;;
        arm-linux-gnueabihf)
            ./Configure --prefix=$ROOT_ARCH_INSTALL linux-armv4 shared
            ;;
        *)
            echo "警告: 未知架构 ${TARGET_ARCH},使用默认配置"
            ./config --prefix=$ROOT_ARCH_INSTALL shared
            ;;
    esac
   
    make -j$(nproc) && make install
    
    if [[ "$?" -ne 0 ]]; then
        echo -e "\033[31m=====build openssl error=====\033[0m"
        exit 1
    fi
}

create_hostapd_config() {
    echo "创建 wpa_supplicant 配置文件..."

    cat > ".config" << EOF
    # wpa_supplicant build configuration
    CONFIG_BACKEND=file
    CONFIG_CTRL_IFACE=y
    CONFIG_CTRL_IFACE_UNIX=y
    CONFIG_DRIVER_NL80211=y
    CONFIG_DRIVER_WEXT=y
    CONFIG_IEEE80211W=y
    CONFIG_IEEE80211R=y
    CONFIG_IEEE80211N=y
    CONFIG_IEEE80211AC=y
    CONFIG_DEBUG_FILE=y
    CONFIG_PEERKEY=y
    CONFIG_TDLS=y
    CONFIG_AP=y
    CONFIG_P2P=y
    CONFIG_READLINE=y
    CONFIG_ELOOP=eloop
    CONFIG_EAPOL_TEST=y
    CONFIG_GETRANDOM=y
    CONFIG_OPTIMIZE_CFLAGS=y
    CONFIG_MAGICLINK=y
    CONFIG_BUILD_WPA_CLIENT_SO=y
EOF
}

compile_hostapd() {
    echo "============ 编译 wpa_supplicant ============"
    if [[ ! -f "${ROOT_DIR}/third_party/wpa_supplicant-2.9" ]]; then
        tar -xvf ${ROOT_DIR}/third_party/wpa_supplicant-2.9.tar.gz -C ${ROOT_ARCH_OUTPUT}
    fi
    cd ${ROOT_ARCH_OUTPUT}/wpa_supplicant-2.9/wpa_supplicant

    create_hostapd_config

    make -j$(nproc) && make install

    if [[ "$?" -ne 0 ]]; then
    echo -e "\033[31m=====build  error=====\033[0m"
    exit 1
    fi
}

main() {
    if [[ ! -f "${ROOT_INSTALL}" ]]; then
        mkdir ${ROOT_INSTALL}
    fi
    if [[ ! -f "${ROOT_ARCH_INSTALL}" ]]; then
        mkdir ${ROOT_ARCH_INSTALL}
    fi
    if [[ ! -f "${ROOT_OUTPUT}" ]]; then
        mkdir ${ROOT_OUTPUT}
    fi
    if [[ ! -f "${ROOT_ARCH_OUTPUT}" ]]; then
        mkdir ${ROOT_ARCH_OUTPUT}
    fi
    
    compile_expat
    compile_dbus
    compile_ncurses
    compile_readline
    compile_libffi
    compile_zlib
    compile_libiconv
    compile_gettext
    compile_glib
    compile_bluez
    compile_libnl
    compile_openssl
    compile_hostapd
}

main "$@"

echo -e "\033[32m=====build successful=====\033[0m"
date +%F' '%H:%M:%S
echo "++++++++++++++++++++++++++++++++++++++++"