#!/usr/bin/python

import boto
from boto.sqs.message import Message
import boto.ec2
import os
import cPickle as pickle
import subprocess
import shlex

import time
import logging
import socket

HOSTNAME = str.join('_', socket.gethostname().split('.'))
FUSE_MOUNT = "/tmp/snowflake"
SERVER_DIR = "/tmp/snowflake_server"

logging.getLogger('boto').setLevel(logging.CRITICAL)
logging.basicConfig(format="%(asctime)s (%(process)d): %(message)s", level=logging.DEBUG, datefmt='%d/%m/%y %H:%M:%S')
logger = logging.getLogger()

def enable_file_logging():
    logfn = "server_%s.log" % HOSTNAME
    logfn = os.path.join(SERVER_DIR, logfn)
    foh = logging.FileHandler(logfn)
    foh.setLevel(logging.DEBUG)
    formatter = logging.Formatter('%(asctime)s (%(process)d): %(message)s', datefmt='%d/%m/%y %H:%M:%S')
    foh.setFormatter(formatter)
    logger = logging.getLogger()
    logger.addHandler(foh)

def mount_s3fs(mnt):
    cmd = "s3fs vishnubob_snowflakes %s -ouse_cache=/tmp" % mnt
    os.system(cmd)

def unmount_s3fs(mnt):
    cmd = "fusermount -u %s" % mnt
    os.system(cmd)

def rsync():
    cmd = "rsync -r %s/ %s" % (SERVER_DIR, FUSE_MOUNT)
    os.system(cmd)

class Job(object):
    SleepCycle = 60

    def __init__(self, cmd):
        self.cmd = cmd
        self.proc = None

    def execute(self):
        self.proc = subprocess.Popen(self.cmd)

    def kill_job(self):
        retry = 10
        self.proc.send_signal(signal.SIGINT)
        # wait a few minues
        while (self.proc.poll() == None) and retry:
            time.sleep(self.SleepCycle)
            retry -= 1
        if not retry:
            self.proc.kill()

    def finished(self):
        if self.proc == None:
            return True
        if self.proc.poll() != None:
            # XXX: log?
            # XXX: clean up?
            self.proc = None
            return True
        return False

class UpdateSource(Job):
    def execute(self):
        cwd = os.getcwd()
        try:
            os.chdir("/tmp")
            cmd = "git pull https://github.com/vishnubob/snowflake.git"
            os.system(cmd)
            cmd = "/tmp/snowflake/utils/deploy.sh"
            os.system(cmd)
        finally:
            os.chdir(cwd)

    def post_process(self):
        msg = "Restarting SnowflakeServer"
        logging.warning(msg)
        args = ["python", "python"] + sys.argv
        os.execlp("/usr/bin/env", *args)
        rsync(self.name, FUSE_MOUNT)

class SnowflakeJob(Job):
    Command = "snowflake.py -s %(size)s -c %(name)s -L"

    def __init__(self, name, size=200):
        self.name = name
        self.size = size
        self.proc = None

    def execute(self):
        kw = {"size": self.size, "name": self.name}
        cmd = self.Command % kw
        msg = "Executing %s" % cmd
        logging.debug(msg)
        cmd = shlex.split(cmd)
        self.proc = subprocess.Popen(cmd)

    def post_process(self):
        rsync(self.name, FUSE_MOUNT)

class SnowflakeMaster(object):
    SleepCycle = 60