# My universal runner for this project, the equivalent of a Makefile
import subprocess, sys, os, shutil, os.path, glob

VERSION='3.4'
RELEASE_NAME='luaunit-%s' % VERSION
ROCK_RELEASE_NAME='rock-%s' % RELEASE_NAME
RELEASE_DIR='release/' + RELEASE_NAME + '/'
RELEASE_TAG='LUAUNIT_V' + VERSION.replace('.', '_')
TARGET_ZIP=RELEASE_NAME + '.zip'
TARGET_TGZ=RELEASE_NAME + '.tgz'
REPO_PATH='d:/work/luaunit/luaunit1'

PATH_LUACHECK='d:\\program\\dev\\lua\\luarocks\\systree\\bin\\luacheck.bat'

LUA51='d:/program/dev/lua/lua51/lua51.exe'
LUA52='d:/program/dev/lua/lua52/lua52.exe'
LUA53='d:/program/dev/lua/lua53/lua53.exe'
LUA54='d:/program/dev/lua/lua54/lua54.exe'
LUAJIT='d:/program/dev/lua/luajit/luajit.exe'
LUAJIT21='d:/program/dev/lua/luajit21/luajit.exe'

ALL_LUA = ( 
    (LUA54, 'Lua 5.4'), 
    (LUA53, 'Lua 5.3'), 
    (LUA52, 'Lua 5.2'), 
    (LUA51, 'Lua 5.1'), 
    (LUAJIT, 'Lua JIT 2.0'), 
    (LUAJIT21, 'Lua JIT 2.1'), 
)

os.environ["nodosfilewarning"] = "1"

def report( s ):
    print( '[[[[[[[[[[[[[ %s ]]]]]]]]]]]]]' % s )

def run_unit_tests():
    '''Run unit-tests with all versions of lua'''
    for lua, luaversion in ALL_LUA:
        report( 'Running unit-tests tests with %s' % luaversion )
        retcode = subprocess.call( [lua, 'run_unit_tests.lua', '--shuffle'] )
        if retcode != 0:
            report( 'Invalid retcode when running tests: %d' % retcode )
            sys.exit( retcode )

def run_tests(with_linting=True):
    '''Run tests with all versions of lua'''
    run_luacheck()
    run_unit_tests()

    for lua, luaversion in ALL_LUA:
        report( 'Running functional tests tests with %s' % luaversion )
        args = [lua, 'run_functional_tests.lua']
        if with_linting:
            args.append('--with-linting')
        retcode = subprocess.call( args )
        if retcode != 0:
            report( 'Invalid retcode when running tests: %d' % retcode )
            sys.exit( retcode )

    report( 'All tests succeed!' )

def run_luacheck():
    report('Running luacheck')
    subprocess.check_call([PATH_LUACHECK, 'example_with_luaunit.lua', 'luaunit.lua', 'run_unit_tests.lua', 'run_functional_tests.lua', 'test/'],
                    shell=True)

def run_example():
    for lua, luaversion in ALL_LUA:
        report( 'Running examples with %s' % luaversion )
        retcode = subprocess.call( [lua, 'example_with_luaunit.lua'] )
        if retcode != 12:
            report( 'Invalid retcode when running examples: %d' % retcode )
            sys.exit( retcode )
    report( 'All examples ran!' )


def pre_packageit_or_buildrock_step1():
    '''
    - create a release directory
    - export the content of the git project but strips
        * git stuff
        * CI stuff (travis, appveyor)
        * doit.py, todo.txt
        * junitxml directory
        * rockspec
        * build documentation and move the html documentation to just doc
    '''
    # shutil.rmtree('release', True)
    try:
        os.mkdir('release')
    except OSError:
        pass
    subprocess.check_call(['d:/program/utils/Git/bin/git.exe', 'clone', '--no-hardlinks', '--branch', RELEASE_TAG, REPO_PATH, RELEASE_DIR])

    os.chdir( RELEASE_DIR )

    # Release dir cleanup. 
    shutil.rmtree('.git')
    os.unlink('.gitignore')
    shutil.rmtree('.travis')
    os.unlink('.travis.yml')
    shutil.rmtree('.appveyor')
    os.unlink('appveyor.yml')
    os.unlink('doit.py')
    os.unlink('TODO.txt')
    shutil.rmtree('junitxml/')

    for p in glob.glob('*.rockspec'):
        os.unlink(p) 

    makedoc()
    # doc cleanup  and simplification
    os.rename( 'doc', 'olddoc' )
    shutil.copytree( 'olddoc/html', 'doc')
    os.unlink('doc/.buildinfo')
    shutil.copy( 'olddoc/my_test_suite.lua', 'doc')
    shutil.rmtree('olddoc/')
    
    run_tests(False)
    run_example()
    os.unlink('.luacheckrc')    # keep it to run the tests successfully

def packageit():
    '''Generate zip and targz archives for a release to GitHub
    '''
    
    pre_packageit_or_buildrock_step1()

    # Packaging into zip and tgz
    os.chdir('..')
    report('Start packaging')
    shutil.make_archive(RELEASE_NAME, 'zip', root_dir='.', base_dir=RELEASE_NAME )
    shutil.make_archive(RELEASE_NAME, 'gztar', root_dir='.', base_dir=RELEASE_NAME )
    report('Zip and tgz ready!')

def buildrock():
    pre_packageit_or_buildrock_step1()

    # Packaging into source rocks
    report('Start preparing rock')
    shutil.move('test/test_luaunit.lua', '.')
    shutil.rmtree('test')
    os.mkdir('test')
    shutil.move('test_luaunit.lua', 'test')
    shutil.move('run_unit_tests.lua', 'test')

    for p in glob.glob('*.lua'):
        if p == 'luaunit.lua': 
            continue
        os.unlink(p) 
    os.unlink('README.md')
    os.unlink('LICENSE.txt')

    os.chdir('..')
    shutil.move( RELEASE_NAME, ROCK_RELEASE_NAME )
    shutil.make_archive( ROCK_RELEASE_NAME, 'zip', root_dir='.', base_dir=ROCK_RELEASE_NAME )


def help():
    print( 'Available actions:')
    for opt in sorted(OptToFunc.keys()):
        print( '\t%s' % opt )

def makedoc():
    os.chdir('doc')
    if os.path.exists('html'):
        shutil.rmtree('html')
    subprocess.check_call(['make.bat', 'html'])
    shutil.copytree('_build/html', 'html')
    os.chdir('..')

def rundoctests():
    lua = LUA52
    for expretcode, l in (
            (0, [ '-e', "lu = require('luaunit');os.exit(lu.LuaUnit.run())" ]),
            (0, [ 'doc/my_test_suite.lua', '-v', 'TestAdd.testAddPositive', 'TestAdd.testAddZero']),
            (0, [ 'doc/my_test_suite.lua', '-v' ]),
            (0, [ 'doc/my_test_suite.lua', ]),
            (0, [ 'doc/my_test_suite.lua', '-o','TAP']),
            (0, [ 'doc/my_test_suite.lua', 'TestAdd', 'TestDiv.testDivError' , '-v']),
            (0, [ 'doc/my_test_suite.lua', '-v', '-p', 'Err.r', '-p', 'Z.ro' ]),
            (0, [ 'doc/my_test_suite.lua', '-v', '--pattern', 'Add', '--exclude', 'Adder', '--pattern', 'Zero' ]),
            (0, [ 'doc/my_test_suite.lua', '-v', '-x', 'Error', '-x', 'Zero' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'text' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'text', '--verbose' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'tap', '--quiet' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'tap' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'tap', '--verbose' ]),
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'nil', '--verbose' ]),
        ):
        print( '%s %s' % ('\n$ lua', ' '.join(l).replace('doc/', '')  ) )
        retcode = subprocess.call( [lua] + l )
        if retcode != expretcode:
            report( 'Invalid luacheck result' )
            sys.exit( retcode )

    for expretcode, l in (
            (2, [ 'doc/my_test_suite_with_failures.lua', '-o', 'junit', '-n', 'toto.xml' ]),
        ):
        print( '%s %s' % ('\n$ lua', ' '.join(l).replace('doc/', '')  ) )
        retcode = subprocess.call( [lua] + l )
        if retcode != expretcode:
            report( 'Invalid luacheck result' )
            sys.exit( retcode )

        print( open('toto.xml').read() )


OptToFunc = {
    'rununittests'  : run_unit_tests,
    'run_unit_tests': run_unit_tests,   # alias
    'runtests'      : run_tests,
    'run_tests'     : run_tests,        # alis
    'luacheck'      : run_luacheck,
    'runexample'    : run_example,
    'packageit'     : packageit,
    'buildrock'     : buildrock,
    'makedoc'       : makedoc,
    'rundoctests'   : rundoctests,
    'help'          : help,
}

if __name__ == '__main__':
    doingNothing = True
    for arg in sys.argv[1:]:
        if arg in OptToFunc:
            doingNothing = False
            OptToFunc[arg]()
        else:
            print( 'No such action :', arg )
            sys.exit(-1)

    if doingNothing:
        help()



