#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import time
import timeit
import signal

import prext

class TimeoutError(Exception):
    def __init__(self, value = "Timed Out"):
        self.value = value

    def __str__(self):
        return repr(self.value)

def timeout(t):
    def decorate(f):
        def handler(signum, frame):
            raise TimeoutError()

        def new_f(*args, **kwargs):
            old = signal.signal(signal.SIGALRM, handler)
            signal.alarm(t)
            try:
                result = f(*args, **kwargs)
            except:
                raise TimeoutError()
            finally:
                signal.alarm(0)
                signal.signal(signal.SIGALRM, old)
            return result

        new_f.func_name = f.func_name
        return new_f

    return decorate

@timeout(600)
def timeout_prext(bookings, k):
    return prext.prext(bookings, k)

@timeout(600)
def timeout_prext_noopt(bookings, k):
    return prext.prext_noopt(bookings, k)

cur_bookings = []
max_time = 0.0
def dynamic_run_prext(bookings, k):
    global cur_bookings, max_time
    bookings.sort(lambda I, J: I.booking_date - J.booking_date)

    cur_bookings = []
    max_time = 0.0

    for i, booking in enumerate(bookings):
        cur_date = booking.booking_date
        cur_bookings.append(booking)

        cur_bookings = [b for b in cur_bookings if b.end_date > cur_date]
        live_bookings = [b for b in cur_bookings if b.start_date < cur_date]

        for b in live_bookings:
            b.movable = False
            b.color = b.orig_color

        cur_time = timeit.Timer("timeout_prext(cur_bookings, k)", "from __main__ import timeout_prext, cur_bookings, k").timeit(1)
        if cur_time > max_time:
            max_time = cur_time

def dynamic_run_prext_noopt(bookings, k):
    global cur_bookings, max_time
    bookings.sort(lambda I, J: I.booking_date - J.booking_date)

    cur_bookings = []
    max_time = 0.0

    for i, booking in enumerate(bookings):
        cur_date = booking.booking_date
        cur_bookings.append(booking)

        cur_bookings = [b for b in cur_bookings if b.end_date > cur_date]
        live_bookings = [b for b in cur_bookings if b.start_date < cur_date]

        for b in live_bookings:
            b.movable = False
            b.color = b.orig_color

        cur_time = timeit.Timer("timeout_prext_noopt(cur_bookings, k)", "from __main__ import timeout_prext_noopt, cur_bookings, k").timeit(1)
        if cur_time > max_time:
            max_time = cur_time

# Data to use and type of camping spot to consider
nordsoe = ("nordsoe.csv", ['Hytte 08m2', 'Hytte 12m2', 'Hytte 16m2', 'Hytte 20m2', 'Hytte 25m2', 'Teltplads', 'Komfortplads', 'El-plads', 'Panoramaplads'])
kolding = ("kolding.csv", ['10 m2 4pers u/udstyr', '15 m2 4pers', '17 m2 4pers', '25 m2 6pers', '25 m2 Luksushytte', 'Teltpladser', 'Campingvogn fortelt', 'Elplads', '2 pers. Hytte m. udstyr'])

sep = " \t& "
runs = 5

# Prext

(f, lst) = nordsoe
sys.stdout.write("  \multirow{9}{9pt}{\\begin{sideways}Nords?? Camping\end{sideways}}\n")
for t in lst:
    (bookings, k) = prext.load_bookings(open(f, 'r'), t)
    sys.stdout.write(" " + sep + str(t) + sep + str(k) + sep + str(len(bookings)) + sep)
    try:
        totaltime = timeit.Timer("timeout_prext(bookings, k)", "from __main__ import timeout_prext, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
    except TimeoutError:
        sys.stdout.write("timeout" + sep)
    try:
        totaltime = timeit.Timer("dynamic_run_prext(bookings, k)", "from __main__ import dynamic_run_prext, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
        sys.stdout.write(("%.2f" + sep) % (totaltime / (float(runs) * len(bookings))))
        sys.stdout.write("%.2f\n" % max_time)
    except TimeoutError:
        sys.stdout.write("timeout" + sep + "timeout" + sep + "timeout\n")
    sys.stdout.flush()

(f, lst) = kolding
sys.stdout.write("  \multirow{9}{9pt}{\\begin{sideways}Kolding Camping\end{sideways}}\n")
for t in lst:
    (bookings, k) = prext.load_bookings(open(f, 'r'), t)
    sys.stdout.write(" " + sep + str(t) + sep + str(k) + sep + str(len(bookings)) + sep)
    try:
        totaltime = timeit.Timer("timeout_prext(bookings, k)", "from __main__ import timeout_prext, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
    except TimeoutError:
        sys.stdout.write("timeout" + sep)
    try:
        totaltime = timeit.Timer("dynamic_run_prext(bookings, k)", "from __main__ import dynamic_run_prext, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
        sys.stdout.write(("%.2f" + sep) % (totaltime / (float(runs) * len(bookings))))
        sys.stdout.write("%.2f\n" % max_time)
    except TimeoutError:
        sys.stdout.write("timeout" + sep + "timeout" + sep + "timeout\n")
    sys.stdout.flush()

sys.stdout.write("\n\n\n")

# Prext without pruning

(f, lst) = nordsoe
sys.stdout.write("  \multirow{9}{9pt}{\\begin{sideways}Nords?? Camping\end{sideways}}\n")
for t in lst:
    (bookings, k) = prext.load_bookings(open(f, 'r'), t)
    sys.stdout.write(" " + sep + str(t) + sep + str(k) + sep + str(len(bookings)) + sep)
    try:
        totaltime = timeit.Timer("timeout_prext_noopt(bookings, k)", "from __main__ import timeout_prext_noopt, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
    except TimeoutError:
        sys.stdout.write("timeout" + sep)
    try:
        totaltime = timeit.Timer("dynamic_run_prext_noopt(bookings, k)", "from __main__ import dynamic_run_prext_noopt, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
        sys.stdout.write(("%.2f" + sep) % (totaltime / (float(runs) * len(bookings))))
        sys.stdout.write("%.2f\n" % max_time)
    except TimeoutError:
        sys.stdout.write("timeout" + sep + "timeout" + sep + "timeout\n")
    sys.stdout.flush()

(f, lst) = kolding
sys.stdout.write("  \multirow{9}{9pt}{\\begin{sideways}Kolding Camping\end{sideways}}\n")
for t in lst:
    (bookings, k) = prext.load_bookings(open(f, 'r'), t)
    sys.stdout.write(" " + sep + str(t) + sep + str(k) + sep + str(len(bookings)) + sep)
    try:
        totaltime = timeit.Timer("timeout_prext_noopt(bookings, k)", "from __main__ import timeout_prext_noopt, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
    except TimeoutError:
        sys.stdout.write("timeout" + sep)
    try:
        totaltime = timeit.Timer("dynamic_run_prext_noopt(bookings, k)", "from __main__ import dynamic_run_prext_noopt, bookings, k").timeit(runs)
        sys.stdout.write(("%.2f" + sep) % (totaltime / float(runs)))
        sys.stdout.write(("%.2f" + sep) % (totaltime / (float(runs) * len(bookings))))
        sys.stdout.write("%.2f\n" % max_time)
    except TimeoutError:
        sys.stdout.write("timeout" + sep + "timeout" + sep + "timeout\n")
    sys.stdout.flush()

sys.stdout.write("\n\n\n")
