#!/usr/bin/python

# Author: Porter Liu

import re
import sys
import json
import string
import urllib2
import os.path

from poster.encode import MultipartParam
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers


# http://foo.com/allbuilds/iOS-client.123/InHouse_123.ipa
configuration_smaple = {
	"base_url"      : "http://foo.com/allbuilds/",
	"build_pattern" : "iOS-client.(\\d+)",
	"build_path"    : "iOS-client.{bn}/InHouse_{bn}.ipa",
	"tot_url"       : "http://bar.com/tot/",
}

def show_configuration_file_syntax():
	print( configuration_smaple )


# we need one argument for configuration file
if len( sys.argv ) != 2:
	print( 'Usage: ' + sys.argv[0] + ' configuration_file' )
	exit( 1 )

# generate build number filename from configuration filename
# for instance: foo.json => foo.buildnumber.txt
temp1, temp2 = os.path.splitext( os.path.basename( sys.argv[1] ) )
buildnumber_filename = temp1 + '.buildnumber.txt';

# open & load configuration in JSON format
try:
	configurationFile = open( sys.argv[1] )
	try:
		config = json.load( configurationFile )
	except Exception, e:
		print( e )
		exit( 1 )
	finally:
		configurationFile.close()
except Exception, e:
	print( e )
	exit( 1 )

# verify configuration file
for key in configuration_smaple.keys():
	if key not in config:
		print( 'Failed to find "' + key + '" in ' + sys.argv[1] )
		show_configuration_file_syntax()
		exit( 1 )

#
# load the last processed build number
#
build_number = 0

if os.path.exists( buildnumber_filename ):
	temp = open( buildnumber_filename, 'r' )
	build_number = string.atoi( temp.read() )
	temp.close()

print( 'old build number = ' + str( build_number ) )

#
# find out the latest build number
#
try:
	remotefile = urllib2.urlopen( config['base_url'] )
	data = remotefile.read()
	remotefile.close()
except Exception, e:
	print( 'failed to access "' + config['base_url'] + '", ' + str( e ) )
	exit( 1 )

temp_build_number = build_number

pattern = config['build_pattern']
po = re.compile( pattern )
mo = po.findall( data )
if mo:
	for item in mo:
		n = string.atoi( item )
		if n > temp_build_number:
			temp_build_number = n

print( 'current max build number = ' + str( temp_build_number ) )

if temp_build_number <= build_number:
	print( 'no new build' )
	sys.exit( 0 )
else:
	build_number = temp_build_number

print( 'will use ' + str( build_number ) + ' as build number' )

#
# generate package url and download
#
url = ( config['base_url'] + config['build_path'] ).format( bn = build_number )
print( 'package URL = ' + url )

package_filename = os.path.basename( url )
print( 'package filename = ' + package_filename )

data = None

try:
	remotefile = urllib2.urlopen( url )
	data = remotefile.read()
	remotefile.close()
except Exception, e:
	print( 'failed to access package URL, ' + str( e ) )
	sys.exit( 1 )

try:
	localFile = open( package_filename, 'wb' )
	localFile.write( data )
	localFile.close()
except Exception, e:
	print( 'failed to create local file, ' + str( e ) )
	sys.exit( 1 )

#
# upload package file onto TOT
#
register_openers()

#datagen, headers = multipart_encode( { 'file' : open( ipa_filename, 'rb' ), 'changelog' : build_name + '.' + str( build_number ), 'submit' : 'Submit' } )
ipa          = MultipartParam.from_file( 'file', package_filename )
ipa.filetype = 'application/octet-stream'
changelog    = MultipartParam( 'changelog', str( build_number ) )
submit       = MultipartParam( 'submit',    'Submit' )
datagen, headers = multipart_encode( [ ipa, changelog, submit ] )

request = urllib2.Request( config['tot_url'] + '/upload.php', datagen, headers )

print urllib2.urlopen( request ).read()

# delete the package
os.remove( package_filename )

#
# save the current build number
#
temp = open( buildnumber_filename, 'w' )
temp.write( str( build_number ) )
temp.close()
