#!/bin/bash
# less — OpenHarmony aarch64-linux-ohos 交叉编译
# OHOS sysroot 通常不含 ncurses:先在本目录 .ohos_deps 下静态编译 ncurses(widec),再编 less。

set -e

export PATH="/usr/bin:/bin:${PATH}"
export PKG_CONFIG=/usr/bin/false

LESS_VER=$(sed -e '/char version\[\]/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q version.c 2>/dev/null || echo "687")
export TREE_INSTALL_HNP_PATH=${HNP_PUBLIC_PATH}/gnu.org/less_${LESS_VER}

sys_prefix=${PREFIX}
export PREFIX=${TREE_INSTALL_HNP_PATH}
echo "${PREFIX}"

SDK_PATH=${OHOS_SDK:?错误: 未设置 OHOS_SDK,请从仓库根目录执行 ./build.sh --sdk <SDK路径> --module less}
SYSROOT=${SYSROOT:-${SDK_PATH}/native/sysroot}

LESS_TOP=$(pwd)

mkdir -p "${TREE_INSTALL_HNP_PATH}/usr/bin"
mkdir -p "${TREE_INSTALL_HNP_PATH}/usr/share/man/man1"
mkdir -p "${TREE_INSTALL_HNP_PATH}/usr/share/terminfo"

DEPS_DIR="${LESS_TOP}/.ohos_deps"
NCPREFIX="${DEPS_DIR}/ncurses-prefix"
NCURSES_VERSION=6.4
# 修改 ncurses 配置时请 bump 后缀,以便重新编译依赖库
NCURSES_STAMP="${DEPS_DIR}/.ncurses_${NCURSES_VERSION}_built_fb2"
NCURSES_TGZ="${DEPS_DIR}/ncurses-${NCURSES_VERSION}.tar.gz"

_NPROC=$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)

download_ncurses() {
    local url ok=0
    for url in \
        "https://mirrors.ocf.berkeley.edu/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz" \
        "https://mirrors.kernel.org/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz" \
        "https://ftp.gnu.org/gnu/ncurses/ncurses-${NCURSES_VERSION}.tar.gz"
    do
        echo "Trying ${url} ..."
        if curl -fsSL --connect-timeout 25 --max-time 600 "${url}" -o "${NCURSES_TGZ}.part"; then
            mv -f "${NCURSES_TGZ}.part" "${NCURSES_TGZ}"
            ok=1
            break
        fi
        rm -f "${NCURSES_TGZ}.part"
    done
    if [ "${ok}" != 1 ]; then
        echo "Error: could not download ncurses-${NCURSES_VERSION}.tar.gz from any mirror"
        exit 1
    fi
}

# 设备上若找不到 terminfo:会报 "terminals database is inaccessible" 或 "<TERM>: unknown terminal type"。
# less 在 TERM 未设置时使用默认名 "unknown",必须在数据库中存在对应条目。
# 策略:优先复制本机构建机上完整的 ncurses terminfo(Homebrew/Linux,约数 MB);否则用 tic 编译扩展子集。
install_less_terminfo() {
    local terminfo_src="${DEPS_DIR}/ncurses-${NCURSES_VERSION}/misc/terminfo.src"
    local terminfo_out="${TREE_INSTALL_HNP_PATH}/usr/share/terminfo"
    if [ ! -f "${terminfo_src}" ]; then
        echo "Error: missing ${terminfo_src}"
        exit 1
    fi
    mkdir -p "${terminfo_out}"

    local copied=0
    for src in /opt/homebrew/opt/ncurses/share/terminfo /usr/local/opt/ncurses/share/terminfo; do
        if [ -d "${src}" ]; then
            echo "Installing terminfo: copying full database from ${src}"
            cp -a "${src}/." "${terminfo_out}/"
            copied=1
            break
        fi
    done

    if [ "${copied}" != 1 ] && [ "$(uname -s)" = Linux ] && [ -d /usr/share/terminfo ]; then
        local sz_k
        sz_k=$(du -sk /usr/share/terminfo 2>/dev/null | awk '{print $1}')
        # 约 25MB 上限,避免在异常巨大目录上耗时/占空间
        if [ -n "${sz_k}" ] && [ "${sz_k}" -le 25600 ]; then
            echo "Installing terminfo: copying /usr/share/terminfo ($((sz_k / 1024)) MB approx)"
            cp -a /usr/share/terminfo/. "${terminfo_out}/"
            copied=1
        fi
    fi

    if [ "${copied}" != 1 ]; then
        echo "Installing terminfo: compiling subset with tic (install Homebrew ncurses for a full DB)..."
        local tic_bin=/usr/bin/tic
        for c in /opt/homebrew/opt/ncurses/bin/tic /usr/local/opt/ncurses/bin/tic; do
            if [ -x "$c" ]; then
                tic_bin="$c"
                break
            fi
        done
        # unknown: less 默认 TERM;其余覆盖常见桌面/SSH/IDE 终端及鸿蒙常见类 xterm 环境
        local entries="unknown,dumb,linux,linux-basic,linux2.6,linux3.0,vt100,vt100-am,vt102,ansi,\
xterm,xterm-256color,xterm-88color,xterm-color,xterm-mono,xterm-direct,\
screen,screen-256color,screen.xterm-256color,tmux,tmux-256color,\
alacritty,kitty,foot,foot-direct,vscode,vte-256color,gnome-256color,konsole-256color,\
st-256color,putty,putty-256color,mlterm,hterm,eterm-color,rxvt,rxvt-256color"
        entries=$(echo "${entries}" | tr -d ' \n')
        if ! "${tic_bin}" -x -e "${entries}" -o "${terminfo_out}" "${terminfo_src}" 2>/dev/null; then
            echo "Note: extended terminfo subset failed with ${tic_bin}; retrying minimal entries..."
            entries="unknown,dumb,linux,vt100,xterm,xterm-color,screen,ansi"
            "${tic_bin}" -x -e "${entries}" -o "${terminfo_out}" "${terminfo_src}" || {
                echo "Error: tic could not compile terminfo (macOS /usr/bin/tic is often too old; install: brew install ncurses)"
                exit 1
            }
        fi
    fi
}

build_ncurses_static() {
    echo "Building static ncurses ${NCURSES_VERSION} for OHOS into ${NCPREFIX}..."
    mkdir -p "${DEPS_DIR}"
    cd "${DEPS_DIR}"
    if [ ! -d "ncurses-${NCURSES_VERSION}" ]; then
        if [ ! -f "${NCURSES_TGZ}" ]; then
            download_ncurses
        fi
        echo "Extracting ncurses..."
        tar -xzf "${NCURSES_TGZ}"
    fi
    cd "ncurses-${NCURSES_VERSION}"
    if [ ! -f "${NCURSES_STAMP}" ]; then
        [ -f Makefile ] && make distclean || true
        # --with-fallbacks 与 lib 构建会调用宿主 tic 处理 terminfo.src;macOS /usr/bin/tic 过旧会失败(如 mintty)
        case "$(uname -s)" in
        Darwin)
            for _ticp in /opt/homebrew/opt/ncurses/bin /usr/local/opt/ncurses/bin; do
                if [ -x "${_ticp}/tic" ]; then
                    export PATH="${_ticp}:${PATH}"
                    echo "Using tic from ${_ticp} for ncurses build"
                    break
                fi
            done
            _tic_which=$(command -v tic)
            if [ "${_tic_which}" = "/usr/bin/tic" ]; then
                echo "Error: macOS /usr/bin/tic (ncurses 6.0) cannot build ncurses 6.4 terminfo / fallbacks."
                echo "Install: brew install ncurses   (then re-run this script)"
                exit 1
            fi
            ;;
        esac
        ./configure \
            --host=aarch64-linux-gnu \
            --prefix="${NCPREFIX}" \
            --without-shared \
            --enable-static \
            --without-debug \
            --without-ada \
            --without-tests \
            --without-manpages \
            --without-progs \
            --enable-widec \
            --with-termlib \
            --with-default-terminfo-dir=/usr/share/terminfo \
            --with-fallbacks=unknown,dumb,vt100,vt102,ansi,linux,linux-basic,linux3.0,xterm,xterm-256color,xterm-color,xterm-mono,screen,screen-256color,tmux,tmux-256color \
            --disable-stripping \
            --without-cxx \
            CC="${CC}" \
            CPP="${CC} -E" \
            AR="${AR}" \
            RANLIB="${RANLIB}" \
            CFLAGS="${CFLAGS}" \
            LDFLAGS="${LDFLAGS}" || {
            echo "Error: ncurses configure failed"
            exit 1
        }
        make -j"${_NPROC}" || {
            echo "Error: ncurses make failed"
            exit 1
        }
        # 交叉编译时完整 install 会运行 tic 写 terminfo,在 macOS 宿主上常失败;仅需静态库与头文件
        make install.includes install.libs || {
            echo "Error: ncurses install.includes/install.libs failed"
            exit 1
        }
        touch "${NCURSES_STAMP}"
    fi
    cd "${LESS_TOP}"
}

build_ncurses_static

if [ ! -x ./configure ] || [ ! -f help.c ]; then
    echo "Generating configure, help.c, funcs.h (git 源码树)..."
    make -f Makefile.aut all || {
        echo "Error: Makefile.aut all failed (need perl, autoconf, autoheader)"
        exit 1
    }
fi

if [ -f Makefile ]; then
    make distclean 2>/dev/null || true
fi

echo "Configuring less..."
# 使用 POSIX 正则,避免宿主 PCRE;终端库由 CPPFLAGS/LDFLAGS 指向静态 ncursesw+tinfow
export CPP="${CC} -E"
./configure \
    --host=aarch64-linux-gnu \
    --prefix=/usr \
    --with-regex=posix \
    CC="${CC}" \
    CPP="${CC} -E" \
    CFLAGS="${CFLAGS}" \
    CPPFLAGS="-I${NCPREFIX}/include -I${NCPREFIX}/include/ncursesw" \
    LDFLAGS="${LDFLAGS} -L${NCPREFIX}/lib" \
    || {
    echo "Error: less configure failed"
    exit 1
}

echo "Building less..."
make -j"${_NPROC}" || {
    echo "Error: less make failed"
    exit 1
}

install_less_terminfo

# git 树默认忽略 *.nro,Makefile 的 install 依赖 less.nro 等;交叉编只需二进制即可
export DESTDIR="${TREE_INSTALL_HNP_PATH}"
export prefix=/usr
install -d "${TREE_INSTALL_HNP_PATH}/usr/bin"
install -c -m 755 lesskey lessecho "${TREE_INSTALL_HNP_PATH}/usr/bin/" || {
    echo "Error: lesskey/lessecho install failed"
    exit 1
}
install -c -m 755 less "${TREE_INSTALL_HNP_PATH}/usr/bin/less.bin" || {
    echo "Error: less binary install failed"
    exit 1
}

# 静态链接的 ncurses 默认只搜编译期路径(如 /usr/share/terminfo),设备上常为空。
# 用启动脚本设置 TERMINFO_DIRS;路径必须随安装位置解析,禁止写死构建机上的 TREE_INSTALL_HNP_PATH。
_less_wrap="${TREE_INSTALL_HNP_PATH}/usr/bin/less"
cat > "${_less_wrap}" <<'WRAPPER'
#!/bin/sh
_me=$0
case $_me in
*/*) ;;
*)
	echo "less: 请通过带目录的路径调用本程序(例如 /path/to/usr/bin/less),勿依赖未解析的 PATH 名称。" >&2
	exit 127
	;;
esac
_bin=${_me%/*}
cd "$_bin" || exit 1
_binroot=$(pwd)
export TERMINFO_DIRS="${_binroot}/../share/terminfo${TERMINFO_DIRS:+:}${TERMINFO_DIRS:-}"
exec "${_binroot}/less.bin" "$@"
WRAPPER
chmod 755 "${_less_wrap}"

cp hnp.json "${TREE_INSTALL_HNP_PATH}/" || {
    echo "Error: failed to copy hnp.json"
    export PREFIX=${sys_prefix}
    exit 1
}

echo "Packaging..."
pushd "${TREE_INSTALL_HNP_PATH}/../" > /dev/null
    ${HNP_TOOL} pack -i "${TREE_INSTALL_HNP_PATH}" -o "${ARCHIVE_PATH}/" || {
        echo "Error: HNP pack failed"
        popd > /dev/null
        export PREFIX=${sys_prefix}
        exit 1
    }
    tar -zvcf "${ARCHIVE_PATH}/ohos_less_${LESS_VER}.tar.gz" "less_${LESS_VER}/" || {
        echo "Error: tar failed"
        popd > /dev/null
        export PREFIX=${sys_prefix}
        exit 1
    }
popd > /dev/null

export PREFIX=${sys_prefix}

echo ""
echo "=========================================="
echo "Build completed successfully!"
echo "=========================================="
echo "HNP: ${ARCHIVE_PATH}/less.hnp"
echo "Tar: ${ARCHIVE_PATH}/ohos_less_${LESS_VER}.tar.gz"
echo "=========================================="
echo ""