#! /usr/bin/python

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.


# This file is used to generate the BuildStamp.java class that
# records the user, url, revision and timestamp.

import os
import sys
import re
import subprocess
import getpass
import time
import socket
import hashlib

def usage():
  print >>sys.stderr, "Usage: saveVersion.py <version> <build_directory>"
  print >>sys.stderr, "Eg:    saveVersion.py  1.1.0  build"


# This template is what gets written to build/src/o.a.h/BuildStamp.java
# It is filled out by (version, revision, user, date, url, srcChecksum)

template_string = \
'''/*
 * Generated by src/saveVersion.py
 */
@HadoopVersionAnnotation(version="%s", revision="%s",
                         user="%s", date="%s", url="%s",
                         srcChecksum="%s")
package org.apache.hadoop;
'''

# Convert Windows paths with back-slashes into canonical Unix paths
# with forward slashes.  Unix paths are unchanged.  Mixed formats
# just naively have back-slashes converted to forward slashes.
def canonicalpath(path):
  return re.sub('\\\\','/',path)

# This is an implementation of md5sum-like functionality in pure python.
# The path name is output in canonical form to get the same aggregate
# checksum as Linux.
def md5sum(fname):
  block_size = 2**20
  f = open(os.path.normpath(fname), 'rb')  # open in binary mode to make sure EOLs don't get munged
  md5 = hashlib.md5()
  while True:
    data = f.read(block_size)
    if not data:
      break
    md5.update(data)
  f.close()
  return "%s %s\n" % (md5.hexdigest(), canonicalpath(fname))

# Roughly emulate the Python 2.7 functionality of "subprocess.check_output()"
# by accepting a CLI vector [cmd, arg1, arg2, ...], and returning its stdout result,
# but without the "checking".  For use in lower version Python interpreters.
def subprocessOutput(args):
  # result = subprocess.check_output(args, shell=True) # requires py2.7
  process = subprocess.Popen(args, stdout=subprocess.PIPE)
  result = process.communicate()[0].strip()
  return result

# Strip surrounding quotes from a string object that carried its quotes with it.
def stripquotes(s):
  if (s[0] == '"' and s[-1] == '"') or (s[0] == "'" and s[-1] == "'") :
    return s[1:-1]
  elif (s[0] == '\\' and s[-1] == '"') :
    return s[1:-1]
  else:
    return s


def main(argv=None):
  if argv is None:
    argv = sys.argv[1:3]
  if (len(argv) != 2) or (argv[0] == "--help") or (argv[0] == "-h"):
    usage()
    return -1

  version = argv[0]
  build_dir = argv[1]

  user = getpass.getuser()
  date = time.strftime("%a %b %d %H:%M:%S %Z %Y")  # simulate `date`

  if os.path.isdir(".git"):
    revision = stripquotes(subprocessOutput(['git', 'log', '-1', '--pretty=format:"%H"']))
    origin = subprocessOutput(['git', 'config', '--get', 'remote.origin.url'])
    branch = subprocessOutput(['git', 'branch'])

    filter_current_branch = re.compile(r'^\* (.*)$', re.MULTILINE)
    current_branch = filter_current_branch.search(branch).group(1).strip()
    url = "%s on branch %s" % (origin, current_branch)
  else:
    svn_info = subprocessOutput(['svn', 'info'])
    filter_last_revision = re.compile(r'^Last Changed Rev: (.*)$', re.MULTILINE)
    revision = filter_last_revision.search(svn_info).group(1).strip()

    filter_url = re.compile(r'^URL: (.*)$', re.MULTILINE)
    url = filter_url.search(svn_info).group(1).strip()

  filter_java = re.compile(r'.+\.java$')
  file_list = []
  for root, dirs, files in os.walk("src"):
    for name in files:
      if filter_java.match(name):
        file_list.append(canonicalpath(os.path.join(root, name)))

  # Sorting is done on unix-format names, case-folded, in order to get a platform-independent sort.
  file_list.sort(key=str.upper)
  file_count = len(file_list)
  hash = hashlib.md5()
  for name in file_list:
    file_hash_string = md5sum(name)
    hash.update(file_hash_string)

  srcChecksum = hash.hexdigest()

  target_dir = os.path.join(os.path.normpath(build_dir),
                            os.path.normpath('src/org/apache/hadoop'))
  if not os.path.exists(target_dir):
    os.makedirs(target_dir)

  target_file = os.path.join(target_dir, 'package-info.java')
  fout = open(target_file, "w")
  fout.write(template_string % (version, revision, user, date, url, srcChecksum))
  fout.close()

  print("Checksummed %s src/**.java files" % file_count)
  return 0

##########################
if __name__ == "__main__":
  sys.exit(main())
