#!/usr/bin/python3

import re, sys, os, time
import concurrent.futures
from requests import get
from bs4 import BeautifulSoup
from time import sleep
from subprocess import check_output

# This file folder
current_path = os.path.dirname(os.path.abspath(__file__))
# Output dir on parent directory
changelog_dest_path = os.path.join(current_path, os.pardir, 'CHANGELOG')
# Debian changelog path
debian_changelog_path = os.path.join(current_path, 'changelog')

# Parse debian/changelog to get current upstream version
latest_debian_changelog = check_output(['dpkg-parsechangelog', '--count', '1', '--file', debian_changelog_path])
latest_debian_version = [ line for line in latest_debian_changelog.splitlines() if line.startswith(b'Version:') ]
latest_debian_version = str(latest_debian_version[0], 'utf-8')
latest_upstream_version = latest_debian_version.split(':')[1].split('-')[0].strip()
print('Most recent upstream version for this package is %s' % latest_upstream_version)

url = 'http://mesos.apache.org/downloads/'
print('Retreiving list of release at %s' % url)

# Parse with BeautifulSoup to convert into a list of tuples (version, changelog)
changelog_tuples = []
resp = get(url)
resp.raise_for_status()
parsed = BeautifulSoup(resp.text, 'html5lib')
# Find <h4>Previous Releases</h4>, get its parent, find <ul>, find all <li>
parsed_changelogs = parsed.body.find('h4', text='Previous Releases').parent.find('ul').find_all('li')

# Turn into a function to be able to use a ThreadPoolExecutor
def get_changelog(url, version):
  resp = get(url)
  resp.raise_for_status()
  parsed_changelog = BeautifulSoup(resp.text, 'html5lib')
  # Text version of changelog is inside <textarea> but contains many empty lines
  changelog_content = parsed_changelog.find('textarea')
  if changelog_content is not None: 
    # replace \n<moar space\n by \n\n
    changelog_content = re.sub(r'\n\s*\n', '\n\n', changelog_content.text).strip()
    return version, changelog_content
  else:
    print('Version %s has no changelog' % version)
    return version, ''

# Let's go threaded
changelogs_tuples = []
futures = {}
failed = False
with concurrent.futures.ThreadPoolExecutor(16) as executor:

  for changelog_entry in parsed_changelogs:
    # Iterates over <li>, two <a> here:
    #   First contains release version
    #   Second contains link to changelog in its href 
    version, changelog_href = changelog_entry.find_all('a')
    version = version.text.strip()
    # Adding url param styleName=Text returns a plain text version
    changelog_url = changelog_href['href'] + '&styleName=Text'
    # Submit in executor
    futures[executor.submit(get_changelog, changelog_url, version)] = (version, changelog_url)

  # Wait for result and get it
  for future in concurrent.futures.as_completed(futures):
    try:
      changelogs_tuples.append(future.result())
      print('Retreived changelog for release %s at %s' % (futures[future][0], futures[future][1]))
    except Exception as e:
      print('Retreiving changelog for version %s at %s FAILED: %s: %s' % (futures[future][0], futures[future][1], e.__class__.__name__, e))
      failed = True

# Is there any future that failed ?
if failed:
  print('RETREIVING CHANGELOG FROM http://mesos.apache.org/downloads/ failed, this is FATAL')
  time.sleep(5)
  sys.exit(1)

# Sort using version
changelog = ''
changelogs_tuples = sorted(changelogs_tuples, key=lambda x: x[0])
for changelogs_tuple in changelogs_tuples:
  # Append and add --- delimiter if changelog exists
  if changelogs_tuple[1]:
    changelog = changelogs_tuple[1] + '\n\n' + '-' * 80 + '\n\n\n' + changelog
  # That's our package version, stop here
  if changelogs_tuple[0] == latest_upstream_version:
    break

with open(changelog_dest_path, 'w+', encoding='utf-8') as fh:
  print(changelog, file=fh)
