#!/bin/bash

umask 0002

base_dir=/srv/share/product/release
package_dir=$base_dir/package
tmp_dir=$base_dir/tmp-for-archive
peace_base_dir=/srv/osstech/www/www.osstech.co.jp/html/download/updates
download_url_base="http://www.osstech.co.jp/download/updates"

## Help
print_help()
{
    local command=$1
    cat <<EOD
SYNOPSIS:
    $command [-i] [-o OS] [-a ARCHITECTURE] [-p PACKAGE] [-h]

DESCRIPTION:
    Use this script for
        1. Send OSSTech product to peace.osstech.co.jp
        2. Make iso image

OPTIONS:
    -i              Switch for making iso image.
    -o OS           Specify OS name. (e.g. RHEL6, RHEL5 Solaris10).
    -a ARCHITECTURE Specify Architecture name. (e.g. x86_64, i386).
    -p PACKAGE      Specify Package name. (e.g. openldap2.4 samba3.6).
    -h              Show this help message and exit.

    When OS, Architecture or Package are not specified, you can select 
    vaid items interactively.

SSH:
    You must be able to access to peace.osstech.co.jp by ssh(1) 
    for sending.

BUNDLE:
    You should bundle before this command.

PACKAGE:
    This command do not support combined packages 
    like samba3.5+openldap2.4+smbldap-tool.

EOD
    exit 0
}

## Common function for list up selection
__listup()
{
    local list=$1
    local message=$2
    local length=0
    local n=1
    for item in $list; do
        local output="[$n]$item "

        # set new line
        if (( $length > 72 )); then
            length=0
            echo 1>&2
        fi

        echo -n "$output" 1>&2

        n=$(( n + 1 ))
        length=$(( length + ${#output} ))
    done;
    echo 1>&2
    echo -n $message 1>&2
}

## Select OS
set_os()
{
    local list=( $( ls $package_dir ) )
    local n

    if [[ "$1" == "" ]]; then
        __listup "${list[*]}" "select os number ==> "
        read n
        n=$(( n - 1 ))
        target_os=${list[$n]}
    else
        target_os=$1
    fi
    return 0
}

## Select architecture
set_arch()
{
    local list=( $( ls $package_dir/$target_os ) )
    local n

    if [[ "$1" == "" ]]; then

        __listup "${list[*]}" "select architecture number ==> "
        read n
        n=$(( n - 1 ))
        target_arch=${list[$n]}
    else
        target_arch=$1
    fi
    return 0
}

## Select package
set_package()
{
    local list=( $( ls $package_dir/$target_os/$target_arch \
                    | grep -v "+" ) )
    local n

    if [[ "$1" == "" ]]; then
        __listup "${list[*]}" "select package number ==> "
        read n
        n=$(( n - 1 ))
        target_package=${list[$n]}
    else
        target_package=$1
    fi
    return 0
}

## Get product name. Product name is derived by core package name.
## Return product name.
get_product_name()
{
    local package_dir=$1
    local package_name=$( basename $package_dir | sed -e "s/[0-9].*//" )

    local product_name=( $( find $package_dir \
                            -name "*${package_name}-[0-9]*.rpm" \
                            | sed -e "s|^.*/\(.*\).rpm|\1|" ) )
    if [[ ${#product_name[@]} != 1 ]]; then
        local n
        __listup "${product_name[*]}" "select product number ==> "
        read n
        n=$(( n - 1 ))
        echo -n ${product_name[$n]}
    else
        echo -n $product_name
    fi
}

# Get document
get_doc()
{
    local package_name=$1
    local cmd_product_doc=$( echo $0 | xargs dirname )/ost-product-doc.ksh
    local doc_list=( $( $cmd_product_doc \
                            $package_name 2> /dev/null \
                        || $cmd_product_doc \
                            ${package_name%%[0-9]*}) )

    if [[ ${#doc_list[@]} != 1 ]]; then
        local n
        __listup "${doc_list[*]}" "select document number ==> "
        read n
        n=$(( n - 1 ))
        echo -n ${doc_list[$n]}
    else
        echo -n $doc_list
    fi
}

## Archive by tar.
## Return sha1 hash.
archive_by_tar()
{
    local product_name=$1
    local target_dir=$2

    echo -n "now archiving..." 1>&2
    mkdir -p $tmp_dir
    rm -rf $tmp_dir/*
    cd $tmp_dir
    mkdir -p $product_name/RPMS
    ln -s $target_dir $product_name/RPMS/
    tar -czf $product_name.tar.gz \
        --dereference \
        --owner 0 \
        --group 0 \
        $product_name \
        ;
    sha1sum $product_name.tar.gz | awk '{print $1}'
    echo "done" 1>&2
}

## Archive by mkisofs.
archive_by_iso()
{
    local product_name=$1
    local target_dir=$2
    local installguide=$( get_doc $target_package )

    echo -n "now archiving..." 1>&2
    mkdir -p $tmp_dir
    rm -rf $tmp_dir/*
    cd $tmp_dir
    mkdir -p $product_name/{docs,pkgs/RPMS}
    cp $installguide $product_name/docs
    ln -s $target_dir $product_name/pkgs/RPMS/
    env TZ=UTC mkisofs -uid 0 -gid 0 \
        -dir-mode 0755 \
        -f -J -R -o $product_name.iso \
        $product_name >/dev/null 2>&1
    echo "done" 1>&2
    echo
    echo "Use this file ==> $tmp_dir/$product_name.iso"
}

## Send archived product.
## Return download url.
send_to_peace()
{
    local product_file=$1
    local peace_dir=$2
    local random_dir

    echo -n "now sending..." 1>&2
    # Retry for duplicating when using pwgen.
    for try in $( seq 3 ); do
        random_dir=$(pwgen -B -1 6)
        ssh -t peace.osstech.co.jp \
            "( umask 0002; \
                mkdir -p $peace_dir; \
                mkdir $peace_dir/$random_dir; )" \
            > /dev/null 2>&1
        [[ $? == "0" ]] && break
    done
    scp $product_file peace.osstech.co.jp:$peace_dir/$random_dir
    ssh -t peace.osstech.co.jp \
        chmod g+w $peace_dir/$random_dir/* > /dev/null 2>&1
    echo "done" 1>&2
    echo $download_url_base/$( basename $peace_dir )/$random_dir/$( basename $product_file )
}

## main section
while getopts io:a:p:h OPT; do
    case $OPT in
        'i') iso_mode=TRUE          ;;
        'o') target_os=$OPTARG      ;;
        'a') target_arch=$OPTARG    ;;
        'p') target_package=$OPTARG ;;
        'h') print_help $0          ;;
    esac
done

set_os $target_os
set_arch $target_arch
set_package $target_package

product_name=$( get_product_name \
    $package_dir/$target_os/$target_arch/$target_package )

if [[ "$iso_mode" == TRUE ]]; then
    archive_by_iso \
        $product_name \
        $package_dir/$target_os/$target_arch/$target_package
    exit 0
else
    sha1sum=$( archive_by_tar \
        $product_name \
        $package_dir/$target_os/$target_arch/$target_package )
    download_url=$( send_to_peace \
        $tmp_dir/$product_name.tar.gz \
        $peace_base_dir/$target_package )
fi

echo
echo "You must edit support page in https://trac.osstech.co.jp."
echo "Use following format."
echo
cat <<EOD
* $target_os($target_arch)
  * $download_url
  * sha1sum: $sha1sum
EOD
