#!/usr/bin/python3

'''Create a series of temporary files for the benefit of code that can't read from stdin'''

import os
import sys
import subprocess

def usage():
    '''Usage message'''
    sys.stderr.write('Usage: %s -c chunkhandlerprog -n nameprefix [-t tmpdir] [-b blocksize]\n' % sys.argv[0])
    sys.stderr.write('-c specifies the chunk handling program to handle each chunk, and is required\n')
    sys.stderr.write('-n specifies the nameprefix to use on all files created, and is required\n')
    sys.stderr.write('-t specifies the temporary directory to write files to, and is optional.  Defaults to $TMPDIR or /tmp\n')
    sys.stderr.write('-b specifies the length of files to create, and is optional.  Defaults to 1 gigabyte\n')
    sys.stderr.write('-d specifies the number of digits to use in filenames.  Defaults to 5\n')
    sys.exit(1)


def pad(number, digits):
    '''
    Pad a number with leading zeros, converting it from an integer to a string.
    Slow on some Pythons.
    '''
    string = str(number)
    while len(string) < digits:
        string = '0' + string
    return string


def process(options):
    '''Process stdin'''
    blockno = 0
    while True:
        if options.verbose:
            sys.stderr.write('Reading block %d\n' % blockno)
        block = sys.stdin.read(options.blocksize)
        if not block:
            break
        if options.verbose:
            sys.stderr.write('Read block of length %d\n' % len(block))
        filename = "%s/%s.%s" % (options.tmpdir, options.nameprefix, pad(blockno, options.digits))
        if options.verbose:
            sys.stderr.write('Writing file %s\n' % filename)
        with open(filename, 'w') as file_:
            file_.write(block)
        command = "%s %s" % (options.prog, filename)
        if options.verbose:
            sys.stderr.write('Performing command %s\n' % command)
        # retval is likely the shell return value * 256, but 0 is still 0, and
        # nonzero is still nonzero
        #retval = os.system(command)
        retval = subprocess.call(command, shell=True)
        if retval == 0:
            if options.verbose:
                sys.stderr.write('Command executed successfully\n')
        else:
            sys.stderr.write('Error executing %s\n' % command)
            sys.stderr.write('Return value from command was %s\n' % str(retval))
            sys.stderr.write('Abnormal termination\n')
            sys.exit(1)
        if options.verbose:
            sys.stderr.write('Deleting %s\n' % filename)
        os.unlink(filename)
        blockno += 1


class Options(object):
    '''Handle command line options'''
    def __init__(self):
        '''Set defaults'''
        self.prog = ''
        self.nameprefix = ''
        if 'TMPDIR' in os.environ:
            self.tmpdir = os.environ['TMPDIR']
        else:
            self.tmpdir = '/tmp'
        self.blocksize = 2**(3*10)
        self.digits = 5
        self.verbose = False


    def handle_argv(self):
        '''Arrange argv into options variables'''
        while sys.argv[1:]:
            if sys.argv[1] == '-c' and sys.argv[2:]:
                self.prog = sys.argv[2]
                del sys.argv[1]
                del sys.argv[1]
            elif sys.argv[1] == '-n' and sys.argv[2:]:
                self.nameprefix = sys.argv[2]
                del sys.argv[1]
                del sys.argv[1]
            elif sys.argv[1] == '-t' and sys.argv[2:]:
                self.tmpdir = sys.argv[2]
                del sys.argv[1]
                del sys.argv[1]
            elif sys.argv[1] == '-b' and sys.argv[2:]:
                self.blocksize = int(sys.argv[2])
                del sys.argv[1]
                del sys.argv[1]
            elif sys.argv[1] == '-b' and sys.argv[2:]:
                self.digits = int(sys.argv[2])
                del sys.argv[1]
                del sys.argv[1]
            elif sys.argv[1] == '-v':
                self.verbose = True
                del sys.argv[1]
            else:
                usage()


    def check(self):
        '''verify options'''
        if self.nameprefix == '' or self.prog == '':
            sys.stderr.write('-n and -c are both required options\n')
            usage()


def main():
    '''Main function'''

    options = Options()
    options.handle_argv()
    options.check()

    process(options)

    if options.verbose:
        sys.stderr.write('Normal termination\n')
    sys.exit(0)


main()