#!/usr/bin/env bash
 
# 生成压缩包 xx.tar.gz或xx.zip
# 使用 ./package.sh -a amd664 -p linux -v v2.0.0
 
# 任何命令返回非0值退出
set -o errexit
# 使用未定义的变量退出
set -o nounset
# 管道中任一命令执行失败退出
set -o pipefail
 
# 二进制文件名
BINARY_NAME=''
# main函数所在文件
MAIN_FILE=""
 
# 提取git最新tag作为应用版本
VERSION=''
# 最新git commit id
GIT_COMMIT_ID=''
 
# 外部输入的系统
INPUT_OS=()
# 外部输入的架构
INPUT_ARCH=()
# 未指定OS,默认值
DEFAULT_OS='linux'
# 未指定ARCH,默认值
DEFAULT_ARCH='amd64'
# 支持的系统
SUPPORT_OS=(linux darwin windows)
# 支持的架构
SUPPORT_ARCH=(386 amd64)
 
# 编译参数
LDFLAGS=''
# 需要打包的文件
INCLUDE_FILE=()
# 打包文件生成目录
PACKAGE_DIR=''
# 编译文件生成目录
BUILD_DIR=''
 
# 获取git 最新tag name
git_latest_tag() {
    local COMMIT_ID=""
    local TAG_NAME=""
    COMMIT_ID=`git rev-list --tags --max-count=1`
    TAG_NAME=`git describe --tags "${COMMIT_ID}"`
 
    echo ${TAG_NAME}
}
 
# 获取git 最新commit id
git_latest_commit() {
    echo "$(git rev-parse --short HEAD)"
}
 
# 打印信息
print_message() {
    echo "$1"
}
 
# 打印信息后推出
print_message_and_exit() {
    if [[ -n $1 ]]; then
        print_message "$1"
    fi
    exit 1
}
 
# 设置系统、CPU架构
set_os_arch() {
    if [[ ${#INPUT_OS[@]} = 0 ]];then
        INPUT_OS=("${DEFAULT_OS}")
    fi
 
    if [[ ${#INPUT_ARCH[@]} = 0 ]];then
        INPUT_ARCH=("${DEFAULT_ARCH}")
    fi
 
    for OS in "${INPUT_OS[@]}"; do
        if [[  ! "${SUPPORT_OS[*]}" =~ ${OS} ]]; then
            print_message_and_exit "不支持的系统${OS}"
        fi
    done
 
    for ARCH in "${INPUT_ARCH[@]}";do
        if [[ ! "${SUPPORT_ARCH[*]}" =~ ${ARCH} ]]; then
            print_message_and_exit "不支持的CPU架构${ARCH}"
        fi
    done
}
 
# 初始化
init() {
    set_os_arch
 
    if [[ -z "${VERSION}" ]];then
        VERSION=`git_latest_tag`
    fi
    GIT_COMMIT_ID=`git_latest_commit`
    LDFLAGS="-w -X 'main.AppVersion=${VERSION}' -X 'main.BuildDate=`date '+%Y-%m-%d %H:%M:%S'`' -X 'main.GitCommit=${GIT_COMMIT_ID}'"
 
    PACKAGE_DIR=${BINARY_NAME}_package
    BUILD_DIR=${BINARY_NAME}_build
 
    if [[ -d ${BUILD_DIR} ]];then
        rm -rf ${BUILD_DIR}
    fi
    if [[ -d ${PACKAGE_DIR} ]];then
        rm -rf ${PACKAGE_DIR}
    fi
 
    mkdir -p ${BUILD_DIR}
    mkdir -p ${PACKAGE_DIR}
}
 
# 编译
build() {
    local FILENAME=''
    for OS in "${INPUT_OS[@]}";do
        for ARCH in "${INPUT_ARCH[@]}";do
            if [[ "${OS}" = "windows"  ]];then
                FILENAME=${BINARY_NAME}.exe
            else
                FILENAME=${BINARY_NAME}
            fi
            env CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH} go build -ldflags "${LDFLAGS}" -o ${BUILD_DIR}/${BINARY_NAME}-${OS}-${ARCH}/${FILENAME} ${MAIN_FILE}
        done
    done
}
 
# 打包
package_binary() {
    cd ${BUILD_DIR}
 
    for OS in "${INPUT_OS[@]}";do
        for ARCH in "${INPUT_ARCH[@]}";do
        package_file ${BINARY_NAME}-${OS}-${ARCH}
        if [[ "${OS}" = "windows" ]];then
            zip -rq ../${PACKAGE_DIR}/${BINARY_NAME}-${VERSION}-${OS}-${ARCH}.zip ${BINARY_NAME}-${OS}-${ARCH}
        else
            tar czf ../${PACKAGE_DIR}/${BINARY_NAME}-${VERSION}-${OS}-${ARCH}.tar.gz ${BINARY_NAME}-${OS}-${ARCH}
        fi
        done
    done
 
    cd ${OLDPWD}
}
 
# 打包文件
package_file() {
    if [[ "${#INCLUDE_FILE[@]}" = "0" ]];then
        return
    fi
    for item in "${INCLUDE_FILE[@]}"; do
            cp -r ../${item} $1
    done
}
 
# 清理
clean() {
    if [[ -d ${BUILD_DIR} ]];then
        rm -rf ${BUILD_DIR}
    fi
}
 
# 运行
run() {
    init
    build
    package_binary
    clean
}

package_gocron() {
    BINARY_NAME='gocron'
    MAIN_FILE="./cmd/gocron/gocron.go"
    INCLUDE_FILE=(Dockerfile-release README.md)


    run
}

package_gocron_node() {
    BINARY_NAME='gocron-node'
    MAIN_FILE="./cmd/node/node.go"
    INCLUDE_FILE=()

    run
}
 
# p 平台 linux darwin windows
# a 架构 386 amd64
# v 版本号  默认取git最新tag
while getopts "p:a:v:" OPT;
do
    case ${OPT} in
    p) IPS=',' read -r -a INPUT_OS <<< "${OPTARG}"
    ;;
    a) IPS=',' read -r -a INPUT_ARCH <<< "${OPTARG}"
    ;;
    v) VERSION=$OPTARG
    ;;
    *)
    ;;
    esac
done
 
package_gocron
package_gocron_node