#!/usr/bin/env python
#
# This script finds an open staging repository, checks that it contains an
# expected artifact, attemps to close the repository, and checks that it is closed.
#

import sys
import json
import time
import os
import requests
from requests.auth import HTTPBasicAuth

USER = os.environ['SONATYPE_USER']
PASSWORD = os.environ['SONATYPE_PASSWORD']
BASE_URL = 'https://oss.sonatype.org/service/local/'
GROUP_ID = 'org.onosproject'
ARTIFACT = 'onos-api'
VERSION = os.environ['ONOS_VERSION']
MAX_TRIES = 10

# Performs an HTTP GET up to MAX_TRIES times
def get(url):
  headers = { 'Accept': 'application/json' }
  error = None
  for i in range(MAX_TRIES):
    resp = requests.get(url, auth=HTTPBasicAuth(USER, PASSWORD), headers=headers)
    try:
      resp.raise_for_status()
      return resp
    except requests.exceptions.HTTPError as e:
      print 'Encountered error:', e
      error = e
      time.sleep(1)
  if error:
    raise error
  return resp

# Performs an HTTP POST with the specified data up to MAX_TRIES times
def post(url, data):
  headers = { 'Accept': 'application/xml', 'Content-type': 'application/xml' }
  error = None
  for i in range(MAX_TRIES):
    resp = requests.post(url, data=data, auth=HTTPBasicAuth(USER, PASSWORD), headers=headers)
    try:
      resp.raise_for_status()
      return resp
    except requests.exceptions.HTTPError as e:
      print 'Encountered error:', e
      error = e
      time.sleep(1)
  if error:
    raise error
  return resp

# Get the staging repos and filter the ones related to onos
def getStagingRepo(groupId):
  resp = get(BASE_URL + 'staging/profile_repositories')
  data = resp.json()['data']
  
  repos = []
  for entry in data:
    if entry['profileName'] == groupId and entry['type'] == 'open':
      repos.append(( entry['repositoryId'], entry['profileId'] ))
  
  if len(repos) > 1:
    print 'Aborting... too many open staging repos'
    print repos
    sys.exit(1)
  elif len(repos) == 0:
    print 'Aborting... there are no open staging repos'
    sys.exit(1)

  return repos[0]  

# Check to make sure the open repo contains the onos-api artifact for the appropriate version
def checkStagingRepo(respositoryId, artifact, groupId, version):
  base = BASE_URL + 'repositories/%s/content/' % repositoryId
  path = '%(groupId)s/%(artifact)s/%(version)s/%(artifact)s-%(version)s.pom' % { 
    'artifact': artifact,
    'groupId': groupId.replace('.','/'),
    'version': version }
  get(base + path) # will raise exception if not present

# Close the repo (Note: /drop can be used to drop the repo, e.g. if failed)
def closeRepo(repositoryId, profileId, version):
  url = BASE_URL + 'staging/profiles/%s/finish' % profileId
  # Argument info: https://oss.sonatype.org/nexus-staging-plugin/default/docs/index.html
  xml = '''<?xml version="1.0" encoding="UTF-8"?>
  <promoteRequest>
    <data>
      <stagedRepositoryId>%s</stagedRepositoryId>
      <description>%s</description>
      <targetRepositoryId>%s</targetRepositoryId>
    </data>
  </promoteRequest>''' % (repositoryId, version, '')
  post(url, xml)
  # Wait for the close to be registered
  time.sleep(3)

# Drop the repo
def dropRepo(repositoryId, profileId):
  url = BASE_URL + 'staging/profiles/%s/drop' % profileId
  # Argument info: https://oss.sonatype.org/nexus-staging-plugin/default/docs/index.html
  xml = '''<?xml version="1.0" encoding="UTF-8"?>
  <promoteRequest>
    <data>
      <stagedRepositoryId>%s</stagedRepositoryId>
      <description></description>
      <targetRepositoryId></targetRepositoryId>
    </data>
  </promoteRequest>''' % (repositoryId)
  post(url, xml)
  # Wait for the close to be registered
  time.sleep(3)

# Check closing status
def checkClose(repositoryId):
  url = BASE_URL + 'staging/repository/%s/activity' % repositoryId
  data = get(url).json()
  closeActivity = None
  for activity in data:
    # find the last close activity
    if activity['name'] == 'close':
      closeActivity = activity 
 
  if not closeActivity:
    return False
 
  for event in activity['events']:
    if event['name'] == 'repositoryClosed':
      return True
    elif event['name'] == 'repositoryCloseFailed':
      print 'Aborting... repository failed to close'
      print json.dumps(activity, sort_keys=True, indent=2, separators=(',', ': '))
      sys.exit(1)
  return False

# Wait until the repository is closed
def waitClosed(repositoryId):
  sys.stdout.write('Closing...')
  sys.stdout.flush()     
  while not checkClose(repositoryId):
    sys.stdout.write('.')
    sys.stdout.flush()     
    time.sleep(2)
  print ' Closed.'

if __name__ == '__main__':
  repositoryId, profileId = getStagingRepo(GROUP_ID)
  print 'Repository Id:', repositoryId
  print 'Profile Id:', profileId

  checkStagingRepo(repositoryId, ARTIFACT, GROUP_ID, VERSION)

  closeRepo(repositoryId, profileId, VERSION)
  
  waitClosed(repositoryId)

  if '-d' in sys.argv:
    print 'Dropping repo %s' % repositoryId
    dropRepo(repositoryId, profileId)
