import web
from sqlalchemy import or_
from clientjob.model import Job
from user.views import get_user
from main.model import Computer
from utils import fancy_datetime
import json
import datetime

PAGE_SIZE = 50

class JobViewDefault:
    def GET(self, page=0):
        return JobView().GET(None, page)

class JobView:
    '''
    Shows the list of child jobs given a parent job.

    If any of the jobs has associated any child jobs, it will show a link to show
    them.
    '''
    def GET(self, parent_id=None, page=0):
        page = int(page)
        orm = web.ctx.orm
        alljobs = orm.query(Job)
        user = get_user()
        jobs = alljobs.filter(Job.parent_id == parent_id).\
                       filter(Job.id >= 1024).order_by(Job.creation_date.desc())\
                            [page*PAGE_SIZE : (page+1)*PAGE_SIZE+1]
        has_more_pages = len(jobs) > PAGE_SIZE
        jobs = jobs[0:PAGE_SIZE]
        jobs = [i for i in jobs if check_job_perm(i, user)]

        parent = alljobs.filter(Job.id == parent_id).first()

        return web.ctx.render.clientjob.list(jobs, parent, fancy_datetime,
                                             page, has_more_pages)



class JobsClearView:
    '''
    Removes all old (30 days), finished and cancelled jobs.
    '''
    def GET(self):
        jobs = web.ctx.orm.query(Job).filter(or_(
                            Job.status.in_(['FINISHED', 'CANCELLED']),
                            Job.creation_date <=
                            datetime.datetime.now()-datetime.timedelta(days=30)
                       )).\
                       filter(Job.id >= 1024)
        for job in jobs:
            web.ctx.orm.delete(job)
        return JobView().GET()

class JobCancel:
    '''
    Cancel a job (and it's childs) and shows it.
    '''
    def GET(self, job_id):
        orm = web.ctx.orm
        alljobs = orm.query(Job)
        user = get_user()
        jobs = alljobs.filter(Job.parent_id == job_id).\
                       filter(Job.id >= 1024).order_by(Job.creation_date.desc())
        parent_job = alljobs.filter(Job.id == job_id).\
                             filter(Job.id >= 1024).one()
        if not parent_job:
                self.error(_('Job "%d" not found') % id)
        parent_job.status = 'CANCELLED'
        for job in jobs:
            if job.status in ('CREATED', 'WAITING'):
                job.status = 'CANCELLED'
        orm.commit()
        return JobView().GET(job_id)


def check_job_perm(job, user):
    if user.super_user:
        return True

    comp = job.computer
    if not comp:
        comps = job.children
        if not comps:
            return False
        return reduce(lambda x, y: x and y, [check_permissions(i, user) for i in comps])
    else:
        return check_permissions(comp, user)


def check_permissions(item, user):
    if item.__class__.__name__ == "OrganizativeUnit":
        if item.parent_id == None and not item in user.organizative_units:
            return False
        elif item in user.organizative_units:
            return True
        else:
            return check_permissions(item.parent, user)
    else:
        return check_permissions(item.ou, user)


class JobStatusAjax:
    def GET(self, job_id):
        orm = web.ctx.orm
        job = orm.query(Job).filter_by(id=job_id).first()
        web.header('Content-Type', 'application/json')
        return json.dumps({'status': job.status,
                           'progress': job.progress,
                           'client_message': job.client_message})
