#!/usr/bin/env 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.
#

#
# Pre Commit Hook for running tests and updating JIRA
#
# Original version was copied from FLUME project.
#
import sys, os, re, urllib2, base64, subprocess, tempfile, shutil
import json
import datetime
from optparse import OptionParser
import xml.etree.ElementTree as ET

tmp_dir = None
BASE_JIRA_URL = 'https://issues.apache.org/jira'

# Write output to file
def write_file(filename, content):
  with open(filename, "w") as text_file:
      text_file.write(content)

# Guess branch for given versions
#
# Return None if detects that JIRA belongs to more than one branch
def sqoop_guess_branch(versions):
  branch = None

  for v in versions:
    tmp_branch = None

    if v.startswith("from/to"):
      tmp_branch = "SQOOP-1367"
    elif v.startswith("1.99") or v.startswith("2.0"):
      tmp_branch = "sqoop2"
    else:
      tmp_branch = "trunk"

    if not branch:
      branch = tmp_branch
    else:
      if branch != tmp_branch:
        return None

  return branch

# Open remote URL
def open_url(url):
  print "Opening URL: %s" % (url)
  return urllib2.urlopen(url)

# Verify supported branch
def sqoop_verify_branch(branch):
  return branch in ("sqoop2", "SQOOP-1082", "SQOOP-1367",)

def execute(cmd, log=True):
  if log:
    print "INFO: Executing %s" % (cmd)
  return subprocess.call(cmd, shell=True)

def jenkins_link_for_jira(name, endpoint):
  if "BUILD_URL" in os.environ:
    return "[%s|%s%s]" % (name, os.environ['BUILD_URL'], endpoint)
  else:
    return name

def jenkins_file_link_for_jira(name, file):
  return jenkins_link_for_jira(name, "artifact/patch-process/%s" % file)

def jira_request(result, url, username, password, data, headers):
  request = urllib2.Request(url, data, headers)
  print "INFO: URL = %s, Username = %s, data = %s, headers = %s" % (url, username, data, str(headers))
  if username and password:
    base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
    request.add_header("Authorization", "Basic %s" % base64string)
  return urllib2.urlopen(request)

def jira_get_defect_html(result, defect, username, password):
  url = "%s/browse/%s" % (BASE_JIRA_URL, defect)
  return jira_request(result, url, username, password, None, {}).read()

def jira_get_defect(result, defect, username, password):
  url = "%s/rest/api/2/issue/%s" % (BASE_JIRA_URL, defect)
  return jira_request(result, url, username, password, None, {}).read()

def jira_color(level):
  if level == ResultItem.INFO:
    return "INFO:"
  elif level == ResultItem.SUCCESS:
    return "{color:green}SUCCESS:{color}"
  elif level == ResultItem.ERROR:
    return "{color:red}ERROR:{color}"
  elif level == ResultItem.FATAL:
    return "{color:red}ERROR:{color}"
  elif level == ResultItem.WARNING:
    return "{color:orange}WARNING:{color}"
  else:
    return level


def jira_generate_comment(result, branch):
  body =  [ "Testing file [%s|%s] against branch %s took %s." % (result.attachment.split('/')[-1] , result.attachment, branch, datetime.datetime.now() - result.start_time) ]
  body += [ "" ]

  if result.overall == "+1":
    body += [ "{color:green}Overall:{color} +1 all checks pass" ]
  else:
    body += [ "{color:red}Overall:{color} -1 due to an error(s), see details below:" ]
  body += [ "" ]

  for item in result._items:
    body += [ "%s %s" % (jira_color(item.level), item.message.replace("\n", "\\n")) ]
    for bullet in item.bullets:
      body += [ "* %s" % bullet ]
    if len(item.bullets) > 0:
      body += [ "\\n" ]

  if "BUILD_URL" in os.environ:
    body += [ "" ]
    body += [ "Console output is available %s." % (jenkins_link_for_jira("here", "console")) ]

  body += [ "" ]
  body += [ "This message is automatically generated." ]
  return "\\n".join(body)

def jira_post_comment(result, defect, branch, username, password):
  url = "%s/rest/api/2/issue/%s/comment" % (BASE_JIRA_URL, defect)

  # Generate body for the comment and save it to a file
  body = jira_generate_comment(result, branch)
  write_file("%s/jira-comment.txt" % output_dir, body.replace("\\n", "\n"))

  # Send the comment to the JIRA
  body = "{\"body\": \"%s\"}" % body
  headers = {'Content-Type' : 'application/json'}
  response = jira_request(result, url, username, password, body, headers)
  body = response.read()
  if response.code != 201:
    msg = """Request for %s failed:
  URL = '%s'
  Code = '%d'
  Comment = '%s'
  Response = '%s'
    """ % (defect, url, response.code, comment, body)
    print "FATAL: %s" % (msg)
    sys.exit(1)

# hack (from hadoop) but REST api doesn't list attachments?
def jira_get_attachment(result, defect, username, password):
  html = jira_get_defect_html(result, defect, username, password)
  pattern = "(/secure/attachment/[0-9]+/(bug)?%s[0-9\-]*((\.|-)v?[0-9]+)?\.(patch|txt|patch\.txt))" % (re.escape(defect))
  matches = []
  for match in re.findall(pattern, html, re.IGNORECASE):
    matches += [ match[0] ]
  if matches:
    matches.sort()
    return  "%s%s" % (BASE_JIRA_URL, matches.pop())
  return None

# Get versions from JIRA JSON object
def json_get_version(json):
  versions = []

  # Load affectedVersion field
  for version in json.get("fields").get("versions"):
    versions = versions + [version.get("name")]

  # Load fixVersion field
  for version in json.get("fields").get("fixVersions"):
    versions = versions + [version.get("name")]

  return versions

def git_checkout(result, branch):
  if not branch:
    result.fatal("Branch wasn't specified nor was correctly guessed")
    return

  if execute("git checkout %s" % (branch)) != 0:
    result.fatal("git checkout %s failed" % branch)
  if execute("git clean -d -f") != 0:
    result.fatal("git clean failed")
  if execute("git reset --hard HEAD") != 0:
    result.fatal("git reset failed")
  if execute("git fetch origin") != 0:
    result.fatal("git fetch failed")
  if execute("git merge --ff-only origin/%s" % (branch)):
    result.fatal("git merge failed")

def git_apply(result, cmd, patch_file, strip, output_dir):
  output_file = "%s/apply.txt" % (output_dir)
  rc = execute("%s -p%s < %s 1>%s 2>&1" % (cmd, strip, patch_file, output_file))
  output = ""
  if os.path.exists(output_file):
    with open(output_file) as fh:
      output = fh.read()
  if rc == 0:
    if output:
      result.warning("Patch applied, but there has been warnings:\n{code}%s{code}\n" % (output))
    else:
      result.success("Patch applied correctly")
  else:
    result.fatal("Failed to apply patch (exit code %d):\n{code}%s{code}\n" % (rc, output))

def static_test(result, patch_file, output_dir):
  output_file = "%s/static-test.txt" % (output_dir)
  rc = execute("grep '^+++.*/test' %s 1>%s 2>&1" % (patch_file, output_file))
  if rc == 0:
    result.success("Patch add/modify test case")
  else:
    result.error("Patch does not add/modify any test case")

def mvn_clean(result, output_dir):
  rc = execute("mvn clean 1>%s/clean.txt 2>&1" % output_dir)
  if rc == 0:
    result.success("Clean was successful")
  else:
    result.fatal("Failed to clean project (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "clean.txt")))

def mvn_rat(result, output_dir):
  rc = execute("mvn apache-rat:check 1>%s/rat.txt 2>&1" % output_dir)
  if rc == 0:
    result.success("License check passed")
  else:
    incorrect_files = []
    for path in list(find_all_files(".")):
      file_name = os.path.basename(path)
      if file_name == "rat.txt":
        fd = open(path)
        for line in fd:
          if "!?????" in line:
            matcher = re.search("\!\?\?\?\?\? (.*)$", line)
            if matcher:
              incorrect_files += [ "{{%s}}" % (matcher.groups()[0]) ]
        fd.close()
    result.error("Failed to run license check (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "rat.txt")), set(incorrect_files))

def mvn_install(result, output_dir):
  rc = execute("mvn install -DskipTests 1>%s/install.txt 2>&1" % output_dir)
  if rc == 0:
    result.success("Patch compiled")
  else:
    result.fatal("failed to build with patch (exit code %d, %s)" % (rc, jenkins_file_link_for_jira("report", "install.txt")))

def find_all_files(top, fileRegExp=".*", dirRegExp=".*"):
    for root, dirs, files in os.walk(top):
        for f in files:
          if re.search(fileRegExp, f) and re.search(dirRegExp, root):
            yield os.path.join(root, f)

def mvn_test(result, output_dir):
  run_mvn_test("test site", "unit", result, output_dir) # Will run cobertura and findbugs as well

def mvn_integration(result, output_dir):
  run_mvn_test("integration-test -pl test", "integration", result, output_dir)

def run_mvn_test(command, test_type, result, output_dir):
  command += " -Pprecommit" # We need special test profile for precommit hook
  test_file_name = "test_%s.txt" % (test_type)
  test_output = "%s/%s" % (output_dir, test_file_name)

  # Execute the test run
  rc = execute("mvn %s 1>%s 2>&1" % (command, test_output))

  # Test run statistics (number of executed/skipped tests)
  executed_tests = 0
  fd = open(test_output)
  for line in fd:
    if "Tests run:" in line:
      matcher = re.search("^Tests run: ([0-9]+), Failures: ([0-9]+), Errors: ([0-9]+), Skipped: ([0-9]+), Time elapsed:", line)
      if matcher:
        executed_tests += int(matcher.group(1))
  fd.close()

  # Based on whether they are
  if rc == 0:
    result.success("All %s tests passed (executed %d tests)" % (test_type ,executed_tests) )
  else:
    failed_tests = []
    for path in list(find_all_files(".")):
      file_name = os.path.basename(path)
      if file_name.startswith("TEST-") and file_name.endswith(".xml"):
        fd = open(path)
        for line in fd:
          if "<failure" in line or "<error" in line:
            matcher = re.search("TEST\-(.*).xml$", file_name)
            if matcher:
               failed_tests += [ "Test {{%s}}" % (matcher.groups()[0]) ]
        fd.close()
    result.error("Some of %s tests failed (%s, executed %d tests)" % (test_type, jenkins_file_link_for_jira("report", test_file_name), executed_tests), set(failed_tests))

def clean_folder(folder):
  for the_file in os.listdir(folder):
      file_path = os.path.join(folder, the_file)
      try:
          if os.path.isfile(file_path):
              os.unlink(file_path)
      except Exception, e:
          print e

# Keep track of actions that we did with their results
class ResultItem(object):
  FATAL = "FATAL"
  ERROR = "ERROR"
  WARNING = "WARNING"
  INFO = "INFO"
  SUCCESS = "SUCCESS"

  def __init__(self, level, message, bullets=[]):
    self.level = level
    self.message = message
    self.bullets = bullets

def cobertura_get_percentage(fd):
  for line in fd:
    if "All Packages" in line:
      matcher = re.search(".*>([0-9]+)%.*>([0-9]+)%.*", line)
      if matcher:
        fd.close()
        return (int(matcher.groups()[0]), int(matcher.groups()[1]))
  fd.close()
  return (-1, -1)

def cobertura_compare(result, output_dir, compare_url):
  # Detailed report file
  report = open("%s/%s" % (output_dir, "cobertura_report.txt"), "w+")
  report.write("Cobertura compare report against %s\n\n" % compare_url)
  # List of all modules for which the test coverage is worst then the compare base
  lowers = []
  # For each report that exists locally
  for path in list(find_all_files(".", "^frame-summary\.html$")):
    package = path.replace("/target/site/cobertura/frame-summary.html", "").replace("./", "")

    remoteIo = None
    try:
      remoteIo = open_url("%s%s" % (compare_url, path))
    except urllib2.HTTPError:
      report.write("Package %s: Base is missing" % (package))
      lowers.append("Package {{%s}}: Can't compare test coverage as base is missing." % (package))
      continue

    (localLine, localBranch) = cobertura_get_percentage(open(path))
    (compareLine, compareBranch) = cobertura_get_percentage(remoteIo)

    diffLine = localLine - compareLine
    diffBranch = localBranch - compareBranch

    report.write("Package %s: Line coverage %d (%d -> %d), Branch coverage %d (%d -> %d)\n" % (package, diffLine, compareLine, localLine, diffBranch, compareBranch, localBranch))

    # Cobertura's percentage calculation doesn't seem to be deterministic - it can do +/- 1% even without change a single line. The goal here is to highlight
    # significant troubles when the coverage is diminished substantially, so we're simply workarounding that by ignoring 1% of difference.
    if diffLine < -1 or diffBranch < -1:
      lowers.append("Package {{%s}} has lower test coverage: Line coverage decreased by %d%% (from %d%% to %d%%), Branch coverage decreased by %d%% (from %d%% to %d%%)" % (package, abs(diffLine), compareLine, localLine, abs(diffBranch), compareBranch, localBranch))

  # Add to the JIRA summary report
  if len(lowers) == 0:
    result.success("Test coverage did not decreased (%s)" % jenkins_file_link_for_jira("report", "cobertura_report.txt"))
  else:
    result.warning("Test coverage has decreased (%s)" % jenkins_file_link_for_jira("report", "cobertura_report.txt"), lowers)

  # Clean up
  report.close()

def findbugs_get_bugs(fd):
  root = ET.parse(fd).getroot()
  bugs = {}
  for file in root.findall("file"):
    classname = file.attrib["classname"]
    errors = len(list(file))
    bugs[classname] = errors
  fd.close()
  return bugs

def findbugs_compare(result, output_dir, compare_url):
  # Detailed report file
  report = open("%s/%s" % (output_dir, "findbugs_report.txt"), "w+")
  report.write("Findbugs compare report against %s\n\n" % compare_url)

  # Lines to be added to summary on JIRA
  summary = []

  # For each report that exists locally
  for path in list(find_all_files(".", "^findbugs\.xml$")):
    package = path.replace("/target/findbugs.xml", "").replace("./", "")

    remoteIo = None
    try:
      remoteIo = open_url("%s%s" % (compare_url, path))
    except urllib2.HTTPError:
      report.write("Package %s: Base is missing" % (package))
      summary.append("Package {{%s}}: Can't compare classes as base is missing." % (package))
      continue

    local = findbugs_get_bugs(open(path))
    remote = findbugs_get_bugs(remoteIo)
    report.write("Processing package %s:\n" % (package))

    # Identify the differences for each class
    for classname, errors in local.iteritems():
      report.write("* Class %s has %s errors.\n" % (classname, errors));
      if classname in remote:
        # This particular class is also known to our compare class
        remoteErrors = remote[classname]
        if(int(errors) > int(remoteErrors)):
          summary.append("Package {{%s}}: Class {{%s}} increased number of findbugs warnings to %s (from %s)" % (package, classname, errors, remoteErrors))
      else:
        # This classes errors are completely new to us
        summary.append("Package {{%s}}: Class {{%s}} introduced %s completely new findbugs warnings." % (package, classname, errors))

    # Spacing between each package
    report.write("\n")

  # Add to JIRA summary
  if len(summary) == 0:
    result.success("No new findbugs warnings (%s)" % jenkins_file_link_for_jira("report", "findbugs_report.txt"))
  else:
    result.warning("New findbugs warnings (%s)" % jenkins_file_link_for_jira("report", "findbugs_report.txt"), summary)

  # Finish detailed report
  report.close()

class Result(object):
  def __init__(self):
    self._items = []
    self.overall = "+1"
    self.exit_handler = None
    self.attachment = "Not Found"
    self.start_time = datetime.datetime.now()
  def error(self, msg, bullets=[]):
    self.overall = "-1"
    self._items.append(ResultItem(ResultItem.ERROR, msg, bullets))
  def info(self, msg, bullets=[]):
    self._items.append(ResultItem(ResultItem.INFO, msg, bullets))
  def success(self, msg, bullets=[]):
    self._items.append(ResultItem(ResultItem.SUCCESS, msg, bullets))
  def warning(self, msg, bullets=[]):
    self._items.append(ResultItem(ResultItem.WARNING, msg, bullets))
  def fatal(self, msg, bullets=[]):
    self.overall = "-1"
    self._items.append(ResultItem(ResultItem.FATAL, msg, bullets))
    self.exit_handler()
    self.exit()
  def exit(self):
    sys.exit(0)

usage = "usage: %prog [options]"
parser = OptionParser(usage)
parser.add_option("--branch", dest="branch",
                  help="Local git branch to test against", metavar="trunk")
parser.add_option("--defect", dest="defect",
                  help="Defect name", metavar="FLUME-1787")
parser.add_option("--file", dest="filename",
                  help="Test patch file", metavar="FILE")
parser.add_option("--run-tests", dest="run_tests",
                  help="Run Tests", action="store_true")
parser.add_option("--run-integration-tests", dest="run_integration_tests",
                  help="Run Integration Tests", action="store_true")
parser.add_option("--username", dest="username",
                  help="JIRA Username", metavar="USERNAME", default="flumeqa")
parser.add_option("--output", dest="output_dir",
                  help="Directory to write output", metavar="DIRECTORY")
parser.add_option("--post-results", dest="post_results",
                  help="Post results to JIRA (only works in defect mode)", action="store_true")
parser.add_option("--password", dest="password",
                  help="JIRA Password", metavar="PASSWORD")
parser.add_option("--patch-command", dest="patch_cmd", default="git apply",
                  help="Patch command such as `git apply' or `patch'", metavar="COMMAND")
parser.add_option("-p", "--strip", dest="strip", default="1",
                  help="Remove <n> leading slashes from diff paths", metavar="N")
parser.add_option("--cobertura", dest="cobertura",
                  help="HTTP URL with past cobertura results that we should compare against")
parser.add_option("--findbugs", dest="findbugs",
                  help="HTTP URL with past findbugs results that we should compare against")

(options, args) = parser.parse_args()
if not (options.defect or options.filename):
  print "FATAL: Either --defect or --file is required."
  sys.exit(1)

if options.defect and options.filename:
  print "FATAL: Both --defect and --file cannot be specified."
  sys.exit(1)

if options.post_results and not options.password:
  print "FATAL: --post-results requires --password"
  sys.exit(1)

branch = options.branch
output_dir = options.output_dir
defect = options.defect
username = options.username
password = options.password
run_tests = options.run_tests
run_integration_tests = options.run_integration_tests
post_results = options.post_results
strip = options.strip
patch_cmd = options.patch_cmd
result = Result()

if os.path.isdir(options.output_dir):
  clean_folder(options.output_dir)

# Default exit handler in case that we do not want to submit results to JIRA
def log_and_exit():
  # Write down comment generated for jira (won't be posted)
  write_file("%s/jira-comment.txt" % output_dir, jira_generate_comment(result, branch).replace("\\n", "\n"))

  for item in result._items:
    print "%s: %s" % (item.level, item.message)
    for bullet in item.bullets:
      print "* %s" % bullet

result.exit_handler = log_and_exit

if post_results:
  def post_jira_comment_and_exit():
    jira_post_comment(result, defect, branch, username, password)
    result.exit()
  result.exit_handler = post_jira_comment_and_exit

if not output_dir:
  tmp_dir = tempfile.mkdtemp()
  output_dir = tmp_dir

if output_dir.endswith("/"):
  output_dir = output_dir[:-1]

if options.output_dir and not os.path.isdir(options.output_dir):
  os.makedirs(options.output_dir)

# If defect parameter is specified let's download the latest attachment
if defect:
  print "Defect: %s" % defect
  jira_json = jira_get_defect(result, defect, username, password)
  json = json.loads(jira_json)

  # JIRA must be in Patch Available state
  if '"Patch Available"' not in jira_json:
    print "ERROR: Defect %s not in patch available state" % (defect)
    sys.exit(1)

  # If branch is not specified, let's try to guess it from JIRA details
  if not branch:
    versions = json_get_version(json)
    branch = sqoop_guess_branch(versions)
    if not branch:
      print "ERROR: Can't guess branch name from %s" % (versions)
      sys.exit(1)

  attachment = jira_get_attachment(result, defect, username, password)
  if not attachment:
    print "ERROR: No attachments found for %s" % (defect)
    sys.exit(1)

  result.attachment = attachment

  patch_contents = jira_request(result, result.attachment, username, password, None, {}).read()
  patch_file = "%s/%s.patch" % (output_dir, defect)

  with open(patch_file, 'a') as fh:
    fh.write(patch_contents)
elif options.filename:
  patch_file = options.filename
else:
  raise Exception("Not reachable")

# Verify that we are on supported branch
if not sqoop_verify_branch(branch):
  print "ERROR: Unsupported branch %s" % (branch)
  sys.exit(1)

mvn_clean(result, output_dir)
git_checkout(result, branch)
git_apply(result, patch_cmd, patch_file, strip, output_dir)
static_test(result, patch_file, output_dir)
mvn_rat(result, output_dir)
mvn_install(result, output_dir)
# Unit tests are conditional
if run_tests:
  mvn_test(result, output_dir)
  # Cobertura report is conditional
  if options.cobertura:
    cobertura_compare(result, output_dir, options.cobertura)
  # Findbugs report is also conditional
  if options.findbugs:
    findbugs_compare(result, output_dir, options.findbugs)
else:
  result.info("Unit tests were skipped, please add --run-tests")
# Integration tests are conditional
if run_integration_tests:
  mvn_integration(result, output_dir)
else:
  result.info("Integration tests were skipped, please add --run-integration-tests")

result.exit_handler()
