#!/bin/bash


function quit {
    echo "Task failed. Exit value: $?."
    cleanUp
    exit 1
}

function cleanUp {
    if [[ -f ${ALIGNED_UNSIGNED_APK} ]]
    then
        rm ${ALIGNED_UNSIGNED_APK}
    fi
    if [[ -f ${ALIGNED_SIGNED_APK} ]]
    then
        rm ${ALIGNED_SIGNED_APK}
    fi
}

# ----Main-----

DO_BUILD=false
DO_SIGN=false
BETA=false
NO_TAG=false
APP_NAME="Bitmask"
FLAVOR="Normal"
FLAVOR_LOWERCASE="normal"
EXPECTED_FINGERPRINT="SHA256:9C:94:DB:F8:46:FD:95:97:47:57:17:2A:6A:8D:9A:9B:DF:8C:40:21:A6:6C:15:11:28:28:D1:72:39:1B:81:AA"



# init parameters
for ((i=1;i<=$#;i++)); 
do
    if [[ ${!i} = "b" || ${!i} = "build" ]] 
    then 
        DO_BUILD=true
        
    elif [[ ${!i} = "s" || ${!i} = "sign" ]] 
    then 
        DO_SIGN=true
        
    elif [[ ${!i} = "-f" || ${!i} = "-file" ]] 
    then 
        ((i++)) 
        FILE_NAME_STRING=${!i}
        FILE_NAME=${FILE_NAME_STRING##*/} #remove everything till the last '/'
        FILE_DIR=${FILE_NAME_STRING%/*} #remove everything after the last '/'

    elif [[ ${!i} = "-ks" || ${!i} = "-keystore" ]] 
    then 
        ((i++)) 
        KEY_STORE_STRING=${!i};
        KEY_STORE_NAME=${KEY_STORE_STRING##*/}
        KEY_STORE_DIR=${KEY_STORE_STRING%/*}
        
    elif [[ ${!i} = "-v" || ${!i} = "-version" ]] 
    then 
        ((i++)) 
        VERSION_NAME=${!i};
        if [[ -z $(git tag --list | grep -w ${VERSION_NAME}) ]] 
        then
            echo "ERROR: Version name has to be a git tag!"
            exit
        fi
    elif [[ ${!i} = "-k" || ${!i} = "-key" ]];
    then 
        ((i++)) 
        GPG_KEY=${!i}    
    elif [[ ${!i} = "-k" || ${!i} = "-key" ]];
    then 
        ((i++)) 
        GPG_KEY=${!i}
    elif [[ ${!i} = "-u" || ${!i} = "-user" ]];
    then 
        ((i++)) 
        GPG_KEY_USER=${!i}
    elif [[ ${!i} = "-b" || ${!i} = "-beta" ]];
    then 
        BETA=true
    elif [[ ${!i} = "-no-tag" ]];
    then 
        NO_TAG=true
    elif [[  ${!i} = "-c" || ${!i} = "-custom" ]]
    then
        ((i++))
        APP_NAME=${!i}
        FLAVOR="Custom"
        FLAVOR_LOWERCASE="custom"
    elif [[ ${!i} = "-h" || ${!i} = "-help" ]];
    then 
        echo -e "
        sign [-ks -fp -f -b -c -u -k]         sign a given apk (both app signing and GPG signing)
        -b / -beta -------------------------- add 'Beta' to filename of resulting apk (optional)
        -c / -custom [appName] -------------- mark build as custom branded Bitmask client and add 
                                              custom app name to resulting apk (required for custom
                                              branded builds)
        -ks / -keystore [path] -------------- define path to keystore for signing (required)
        -fp / -fingerprint [fingerprint] ---- define the fingerprint for the app (required for non-LEAP
                                              signed apps)
        -f / -file [inputfile] -------------- define path to apk going to be signed (required if 
                                              sign command is not used in conjuction with build)
        -v / -version [gittag] -------------- define app version as part of the resulting apk file
                                              name. If not used, 'latest' will be added instead
        -u / -user [gpguser] ---------------- define the gpg user whose key will be used for GPG signing
                                              (optional)
        -k / -key [gpgkey] ------------------ define the key used for GPG signing. Using this option,
                                              -u will be ignored (optional)                           
        
        
        build [-v, -c, -b, -no-tag]
        -v / -version [gittag] -------------- define the git version tag that needs to be checked out 
                                              for building. It's also part of the resulting apk file 
                                              name. (required if you don't use -no-tag)
        -c / -custom ------------------------ build custom Bitmask client instead of main Bitmask client 
                                              (optional)
        -b / -beta -------------------------- build beta version with .beta appended to applicationId (optional)
        -no-tag ----------------------------- force to build current checked out git commit instead of an
                                              official release version

        
        -h / -help                            print out this help
        
        
        example Usages:
        ---------------
        
        * jarsign only:
        ./prepareForDistribution.sh sign -f app/build/outputs/apk/app-production-beta.apk -ks ~/path/to/bitmask-android.keystore -v 0.9.7
        
        * jarsign and gpg sign only:
        ./prepareForDistribution.sh sign -f app/build/outputs/apk/app-production-beta.apk -ks ~/path/to/bitmask-android.keystore -u GPG_USER -v 0.9.7
        
        * build custom stable
        ./prepareForDistribution.sh build -v 0.9.7 -c RiseupVPN
        
        * build and sign custom stable:
        ./prepareForDistribution.sh build sign -ks ~/path/to/bitmask-android.keystore -u GPG_USER -v 0.9.7 -c RiseupVPN
        
        * build and sign custom beta:
        ./prepareForDistribution.sh build sign -ks ~/path/to/bitmask-android.keystore -u GPG_USER -b -v 0.9.7RC2 -c RiseupVPN

        * build and sign stable:
        ./prepareForDistribution.sh build sign -ks ~/path/to/bitmask-android.keystore -u GPG_USER -v 0.9.7
        
        * build and sign current git HEAD
        ./prepareForDistribution.sh build sign -ks ~/path/to/bitmask-android.keystore -u GPG_USER -no-tag"
        exit

    else
        echo "Invalid argument: ${!i}"
        exit
    fi

done;


# check what to do
if [[ ${DO_BUILD} == false && ${DO_SIGN} == false ]]
then
    echo "ERROR: No action set. Please check  ./prepareForDistribution -help!"
    exit
fi

if [[ ${DO_BUILD} == true ]]
then
    if [[ ${NO_TAG} == false && -z ${VERSION_NAME} ]]
    then
        echo "ERROR: You didn't enter the version (git tag) to be built. If you really want to force building the current checked out commit, use -no-tag."
        quit
    fi
    if [[ ${NO_TAG} == false ]] 
    then
        #---- COMPARE TAG COMMIT WITH CURRENT COMMIT AND CHECK OUT TAG COMMIT IF NECESSARY ----
        TAG_COMMIT=$(git log -n 1 ${VERSION_NAME} --format="%H")
        CURRENT_COMMIT=$(git log -n 1 --format="%H")
        if [[ ${TAG_COMMIT} != ${CURRENT_COMMIT} ]]
        then
            echo "CHECKING OUT VERSION: ${VERSION_NAME} ..."
            git checkout ${VERSION_NAME} || quit
        fi
    fi

    ./cleanProject.sh || quit
    ./build_deps.sh || quit
    
    if [[ ${BETA} == true ]]
    then
        ./gradlew clean assemble${FLAVOR}ProductionBeta --stacktrace || quit
    else
        ./gradlew clean assemble${FLAVOR}ProductionRelease --stacktrace || quit
    fi
fi

if [[ ${DO_SIGN} == true ]]
then
    # check global vars
    if [[ -z ${ANDROID_BUILD_TOOLS} ]] 
    then
        echo "ERROR: Environment variable ANDROID_BUILD_TOOLS not set! Please add it to your environment variables. Exiting."
        exit 
    fi

    if [[ -z ${FILE_NAME} && ${DO_BUILD} == false ]] 
    then
        echo -e "ERROR: Sign only needs a file name. Please check ./prepareForDistribution -help!"
        exit
    fi
    if [[ -z ${KEY_STORE_NAME} ]] 
    then
        echo "ERROR: Key store not set. Please check ./prepareForDistribution -help"
        exit
    fi
    if [[ -n ${FILE_NAME_STRING} && ${DO_BUILD} == true ]]
    then
        echo "WARNING: Ignoring parameter -file. Built APK will be used instead."
    fi
    
    #---- OPT: SELECT APK FROM LAST BUILD ----
    if [[ ${DO_BUILD} == true ]]
    then
        BASE_FILE_DIR="$(pwd)/app/build/outputs/apk"
        if [[ ${BETA} == true ]]
        then
            FILE_NAME="app-${FLAVOR_LOWERCASE}-production-beta.apk"
            BUILD_TYPE_DIR="beta"
        else
            FILE_NAME="app-${FLAVOR_LOWERCASE}-production-release.apk"
            BUILD_TYPE_DIR="release"
        fi
        if [[ ${FLAVOR_LOWERCASE} == "normal" ]] 
        then
            FLAVOR_DIR="normalProduction"
        else
            FLAVOR_DIR="customProduction"
        fi
        FILE_DIR="${BASE_FILE_DIR}/${FLAVOR_DIR}/${BUILD_TYPE_DIR}"
    fi
    
    #---- ALIGN AND JARSIGN APK  -----
    ALIGNED_UNSIGNED_APK="${FILE_DIR}/aligned-${FILE_NAME}"
    ALIGNED_SIGNED_APK="${FILE_DIR}/aligned-signed-${FILE_NAME}"

    ${ANDROID_BUILD_TOOLS}/zipalign -v -p 4 "${FILE_DIR}/${FILE_NAME}" ${ALIGNED_UNSIGNED_APK} || quit
    ${ANDROID_BUILD_TOOLS}/apksigner sign --ks "${KEY_STORE_STRING}" --out ${ALIGNED_SIGNED_APK} ${ALIGNED_UNSIGNED_APK} || quit
    rm ${ALIGNED_UNSIGNED_APK}
    
    FINGERPRINT=$(unzip -p ${ALIGNED_SIGNED_APK} META-INF/*.RSA | keytool -printcert | grep "SHA256" | tr -d '[:space:]') || quit
    
    if [[ ${FINGERPRINT} == ${EXPECTED_FINGERPRINT} ]] 
    then
        echo "Certificate fingerprint matches: ${FINGERPRINT}"
    else 
        echo -e "Certificate fingerprint \n${FINGERPRINT} \ndid not match expected fingerprint \n\t${EXPECTED_FINGERPRINT}"
        quit
    fi
    
    #---- RENAME TO VERSION_NAME ----
    FINAL_APK=${ALIGNED_SIGNED_APK}
    if [[ -z ${VERSION_NAME} ]] 
    then
        VERSION_NAME="latest"
    fi

    if [[ ${BETA} == true ]]
    then
        FINAL_FILE_NAME="${APP_NAME}-Android-Beta-${VERSION_NAME}.apk"
    else 
        FINAL_FILE_NAME="${APP_NAME}-Android-${VERSION_NAME}.apk"
    fi
    FINAL_APK="${FILE_DIR}/${FINAL_FILE_NAME}"
    cp ${ALIGNED_SIGNED_APK} ${FINAL_APK} || quit
    cleanUp

    
    #---- GPG SIGNING ----
    if [[ -z ${GPG_KEY} && -z ${GPG_KEY_USER} ]] 
    then
        echo "WARNING: Could not do gpg signing!"
        exit
    fi
    
    if [[ ${GPG_KEY} ]] 
    then
        gpg --default-key ${GPG_KEY} --armor --output "${FINAL_APK}.sig" --detach-sign ${FINAL_APK} || quit
        #gpg -u ${GPG_KEY} -sab --output ${FINAL_APK} || quit
    else 
        GPG_KEY=$(gpg --list-keys $GPG_KEY_USER | grep pub | cut -d '/' -f 2 | cut -d ' ' -f 1) || quit
        #gpg -u ${GPG_KEY} -sab --output ${FINAL_APK} || quit
        gpg --default-key ${GPG_KEY} --armor --output "${FINAL_APK}.sig" --detach-sign ${FINAL_APK} || quit
    fi
    
    gpg --verify "${FINAL_APK}.sig" || quit
    
fi