import sys
import os
import re

SVN_REVISION_FILE = '../Builder/svn-revision.txt'

class BrandingError(Exception):
    pass

class BrandVersion:
    def __init__( self ):
        # create dictionary of branding strings
        self.branding_info = {}
        self.version_details = None
        self.input_filename = None
        self.output_filename = None

    def main( self, argv ):
        try:
            self.version_details = argv[1]
            self.input_filename = argv[2]
            self.output_filename = self.input_filename[:-len('.template')]

            self.loadVersionDetails()
            self.setBuildFromRevision()

            self.brandFile()
            return 0

        except BrandingError as e:
            print( 'Error: %s' % (e,) )
            return 1

    def brandFile( self ):
        # read all the input text
        with open( self.input_filename, 'r' ) as f:
            text = f.read()
        # and write of a branded version
        with open( self.output_filename, 'w' ) as f:
            f.write( text % self.branding_info )

    def loadVersionDetails( self ):
        with open( self.version_details ) as f:
            for line in f:
                line = line.strip()
                if len(line) == 0:
                    continue
                if line[0:1] == ['#']:
                    continue

                key, value = [s.strip() for s in line.split('=',1)]
                self.branding_info[ key ] = value

    def setBuildFromRevision( self ):
        if os.path.exists( SVN_REVISION_FILE ):
            with open( SVN_REVISION_FILE ) as f:
                build_revision = f.read().strip()

                if build_revision[0] not in '0123456789':
                    raise BrandingError( 'Error: bad revision %r from %s' % (build_revision, SVN_REVISION_FILE) )

        else:
            build_revision = self.getBuildFromRevisionUsingSvnversion()

        # build_revision is either a range nnn:mmm or mmm
        # we only want the mmm
        build_revision = build_revision.split(':')[-1]
        print( 'Info: revision %s' % (build_revision,) )

        if build_revision[0] not in '0123456789':
            self.branding_info['BUILD'] = '0'
            return

        revision, modifiers = re.compile( r'(\d+)(.*)' ).search( build_revision ).groups()

        if modifiers:
            self.branding_info['BUILD'] = '0'
        else:
            self.branding_info['BUILD'] = revision

    def getBuildFromRevisionUsingSvnversion( self ):
        svnversion_image = os.environ.get( 'WC_SVNVERSION', '/usr/bin/svnversion' )
        if not os.path.exists( svnversion_image ):
            raise BrandingError( 'Error: svnversion image not found at %r' % (svnversion_image,) )

        # os.popen fails to run a quoted image that does not have a space in it path
        if ' ' in svnversion_image:
            cmd = ('"%s" -c "%s" 2>&1' %
                (svnversion_image
                ,os.environ.get( 'PYSVN_EXPORTED_FROM', '..' )))
        else:
            cmd = ('%s -c "%s" 2>&1' %
                (svnversion_image
                ,os.environ.get( 'PYSVN_EXPORTED_FROM', '..' )))

        print( 'Info: Running %s' % cmd )
        build_revision = os.popen( cmd, 'r' ).read().strip()

        if build_revision[0] not in '0123456789':
            raise BrandingError( 'Error: svnversion %r bad output %r' % (svnversion_image, build_revision) )

        return build_revision



if __name__ == '__main__':
    sys.exit( BrandVersion().main( sys.argv ) )
