#!/usr/bin/env python2.7
# Copyright (c) 2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os, os.path, shutil, signal, socket, sys
from os import environ as env
from os.path import join as joinpath, expanduser

def date():
    import time
    return time.strftime('%a %b %e %H:%M:%S %Z %Y', time.localtime())

def cleandir(dir):
    for root, dirs, files in os.walk(dir, False):
        for name in files:
            os.remove(joinpath(root, name))
        for name in dirs:
            os.rmdir(joinpath(root, name))

class rsync:
    def __init__(self):
        self.sudo = False
        self.rsync = 'rsync'
        self.compress = False
        self.archive = True
        self.delete = False
        self.options = ''

    def do(self, src, dst):
        args = []
        if self.sudo:
            args.append('sudo')

        args.append(self.rsync)
        if (self.archive):
            args.append('-a')
        if (self.compress):
            args.append('-z')
        if (self.delete):
            args.append('--delete')
        if len(self.options):
            args.append(self.options)
        args.append(src)
        args.append(dst)

        return os.spawnvp(os.P_WAIT, args[0], args)

class JobDir(object):
    def __init__(self, dir):
        self.dir = dir

    def file(self, filename):
        return joinpath(self.dir, filename)

    def create(self):
        if os.path.exists(self.dir):
            if not os.path.isdir(self.dir):
                sys.exit('%s is not a directory.  Cannot build job' % self.dir)
        else:
            os.mkdir(self.dir)

    def exists(self):
        return os.path.isdir(self.dir)

    def clean(self):
        cleandir(self.dir)

    def hasfile(self, filename):
        return os.path.isfile(self.file(filename))

    def echofile(self, filename, string):
        filename = self.file(filename)
        try:
            f = file(filename, 'w')
            print >>f, string
            f.flush()
            f.close()
        except IOError,e:
            sys.exit(e)

    def rmfile(self, filename):
        filename = self.file(filename)
        if os.path.isfile(filename):
            os.unlink(filename)

    def readval(self, filename):
        filename = self.file(filename)
        f = file(filename, 'r')
        value = f.readline().strip()
        f.close()
        return value

    def setstatus(self, string):
        filename = self.file('.status')
        try:
            f = file(filename, 'a')
            print >>f, string
            f.flush()
            f.close()
        except IOError,e:
            sys.exit(e)

    def getstatus(self):
        filename = self.file('.status')
        try:
            f = file(filename, 'r')
        except IOError, e:
            return 'none'

        # fast forward to the end
        for line in f: pass

        # the first word on the last line is the status
        return line.split(' ')[0]

    def __str__(self):
        return self.dir

if __name__ == '__main__':
    rootdir = env.setdefault('ROOTDIR', os.getcwd())
    pbs_jobid = env['PBS_JOBID']
    pbs_jobname = env['PBS_JOBNAME']
    basedir = joinpath(rootdir, 'Base')
    jobname = env.setdefault('JOBNAME', pbs_jobname)
    jobfile = env.setdefault('JOBFILE', joinpath(rootdir, 'Test.py'))
    outdir = env.setdefault('OUTPUT_DIR', joinpath(rootdir, jobname))
    env['POOLJOB'] = 'True'

    if os.path.isdir("/work"):
        workbase = "/work"
    else:
        workbase = "/tmp/"

    workdir = joinpath(workbase, '%s.%s' % (env['USER'], pbs_jobid))
    host = socket.gethostname()

    os.umask(0022)

    jobdir = JobDir(outdir)

    started = date()
    jobdir.echofile('.running', started)
    jobdir.rmfile('.queued')
    jobdir.echofile('.host', host)

    jobdir.setstatus('running on %s on %s' % (host, started))

    if os.path.isdir(workdir):
        cleandir(workdir)
    else:
        os.mkdir(workdir)

    if False and os.path.isdir('/z/dist'):
        sync = rsync()
        sync.delete = True
        sync.sudo = True
        sync.do('poolfs::dist/m5/', '/z/dist/m5/')

    try:
        os.chdir(workdir)
    except OSError,e:
        sys.exit(e)

    os.symlink(jobdir.file('output'), 'status.out')

    args = [ joinpath(basedir, 'm5'), joinpath(basedir, 'run.py') ]
    if not len(args):
        sys.exit("no arguments")

    print 'starting job... %s' % started
    print ' '.join(args)
    print
    sys.stdout.flush()

    childpid = os.fork()
    if not childpid:
        # Execute command
        sys.stdin.close()
        fd = os.open(jobdir.file("output"),
                     os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
        os.dup2(fd, sys.stdout.fileno())
        os.dup2(fd, sys.stderr.fileno())
        os.execvp(args[0], args)

    def handler(signum, frame):
        if childpid != 0:
            os.kill(childpid, signum)

    signal.signal(signal.SIGHUP, handler)
    signal.signal(signal.SIGINT, handler)
    signal.signal(signal.SIGQUIT, handler)
    signal.signal(signal.SIGTERM, handler)
    signal.signal(signal.SIGCONT, handler)
    signal.signal(signal.SIGUSR1, handler)
    signal.signal(signal.SIGUSR2, handler)

    done = 0
    while not done:
        try:
            thepid,ec = os.waitpid(childpid, 0)
            if ec:
                print 'Exit code ', ec
                status = 'failure'
            else:
                status = 'success'
            done = 1
        except OSError:
            pass

    complete = date()
    print '\njob complete... %s' % complete
    jobdir.echofile('.%s' % status, complete)
    jobdir.rmfile('.running')
    jobdir.setstatus('%s on %s' % (status, complete))
