#!/usr/bin/env bash
#
# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# 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 PROGram name
PROG=${0##*/}
########################################################################
#+
#+ NAME
#+     $PROG - What tag(s) is my PR IN?
#+
#+ SYNOPSIS
#+     $PROG  <commit|pr>
#+     $PROG  [--security_layer=/path/to/pointer/to/script]
#+     $PROG  [--helpshort|--usage|-?]
#+     $PROG  [--help|-man]
#+
#+ DESCRIPTION
#+     Report the tags in which a PR or commit appears and the latency in
#+     days (commit to release).
#+
#+ OPTIONS
#+     [--security_layer=]       - A file containing a path to a script to
#+                                 source/include:
#+                                 FLAGS_security_layer=/path/to/script
#+                                 Default: $HOME/.kubernetes-releaserc
#+     [--help | -man]           - display man page for this script
#+     [--usage | -?]            - display in-line usage
#+
#+ EXAMPLES
#+
#+ FILES
#+
#+ SEE ALSO
#+     common.sh                 - base function definitions
#+
#+ BUGS/TODO/IDEAS
#+     Limit results to first tag/release per branch
#+
########################################################################
# If NO ARGUMENTS should return *usage*, uncomment the following line:
usage=${1:-yes}

source $(dirname $(readlink -ne $BASH_SOURCE))/lib/common.sh
source $TOOL_LIB_PATH/gitlib.sh

###############################################################################
# FUNCTIONS
###############################################################################

#############################################################################
# Display/Report tags and latency (to release) for the incoming commits
# K8S latency is the difference between the commit timestamp and tag timestamp
# @param pr - a PR or "" (placeholder)
# @param commits - a list of commits
# HOSTED_EPOCH is set by an external script
show_tags () {
  local pr=$1
  local initial_commit=$2
  shift 2
  local cp_commits=($*)
  local commit
  local commit_seconds
  local tag_seconds
  local tag
  local days
  local hosted_days

  logecho
  logecho "COMMITS: $initial_commit (initial) ${cp_commits[*]} (cherrypicks)"
  [[ -n $pr ]] && echo "(https://github.com/kubernetes/kubernetes/pull/$pr)"
  logecho
  logecho "                LATENCY TO APPEAR (DAYS)"
  logecho -n "TAG             K8S"
  if ((SECURITY_LAYER)); then
    logecho "     HOSTED"
  else
    logecho
  fi
  logecho -n "---             ---"
  if ((SECURITY_LAYER)); then
    logecho "     ------"
  else
    logecho
  fi

  # We only care about the initial commit for latency calculation
  commit_seconds=$(git show -s --format="%ct" $initial_commit)

  for commit in $initial_commit ${cp_commits[*]}; do
    for tag in $(git tag --contains $commit); do
      tag_seconds=$(git show -s --pretty=format:%ct $tag |tail -1)

      # Convert to days with some precision
      days=$(echo "scale=2; ($tag_seconds-$commit_seconds)/86400"|bc)

      if ((SECURITY_LAYER)); then
        hosted_days="NA"
        [[ -n "${HOSTED_EPOCH[$tag]}" ]] && \
         hosted_days=$(echo "scale=2; (${HOSTED_EPOCH[$tag]}-$commit_seconds)/86400"|bc)
      fi

      printf "%-15s %-7s %s\n" "$tag" "$days" "$hosted_days"
    done
  done
  echo
}

###############################################################################
# Stubbed out
security_layer::hosted_map () {
  logecho "Skipping $FUNCNAME extensions..."
  return 0
}


###############################################################################
# MAIN
###############################################################################
# Are we in a repo?
gitlib::current_branch >/dev/null || common::exit 1

# Additional functionality
common::security_layer

if [[ ${POSITIONAL_ARGV[0]} =~ [0-9]{5,} ]]; then
  PR=${POSITIONAL_ARGV[0]}
  #echo "Converting incoming PR to a commit..."
  # Need to include --all for the primary commit too for
  # non-cherrypick commit searches on branches
  INITIAL_COMMIT=$(git log --grep "Merge pull request #$PR" \
                           --all --pretty=format:"%h")
  CP_COMMITS=($(git log --grep "cherry-pick-of-.*#$PR-" \
                        --all --pretty=format:"%h"))
else
  # TODO: Need to validate this is a git hash
  INITIAL_COMMIT=("${POSITIONAL_ARGV[0]}")
fi

[[ -z "$INITIAL_COMMIT" ]] && common::exit 1 "No commit/pr found in this repo."

security_layer::hosted_map

show_tags "$PR" $INITIAL_COMMIT ${CP_COMMITS[*]}
