#!/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.
#
# Authors: Nathan Binkert
#          Steve Reinhardt
#          Ali Saidi

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))
