'''
Inventory Hardware Module
'''

from __future__ import unicode_literals
from ..pluginbase import PluginBase
from ..action import ActionInstance
from model import HardwareElement, HardwareProfile
from jobs import RequestHardwareProfileJob
from main.model import Computer, OrganizativeUnit
from clientjob.model import Job
import web
import views
import db
from sqlalchemy.orm.exc import NoResultFound
# import view
#import searchbyhardware
import config

class Plugin(PluginBase):
    '''
    Manages the hardware of the computers.
    It tries to get this information automatically.
    Later you can find computers by its hardware.
    '''
    def enable(self):
        self.urls = ('view/(profile|computer)/(\w+)',
                views.ProfileHardwareView,
                'action/viewprofile/(computer)/(\w+)',
                views.ProfileHardwareView,
                #'action/searchbyhardware/(\w+)/(\w+)',
                #searchbyhardware.SearchByHardwareView)
                'action/updatehardwareprofile/(\w+)',
                views.UpdateHardwareView)

    def disable(self):
        pass

    def install(self):
        '''
        In the installation we send to each computer the request
        to know their hardware.
        '''
        # Creating the job to send to the computers
        computers = web.ctx.orm.query(Computer).all()
        group_job = RequestHardwareProfileJob(computers=computers)
        web.ctx.orm.add(group_job)
        web.ctx.orm.commit()
        print web.ctx.orm
        group_job.send()

    def uninstall(self):
        pass

    def get_options(self):
        return web.form.Form(
                web.form.Textbox('des', description='Descripcion'))

    def save_options(self, values):
        print values.des

    def send_job_create_hardware(self, computer_id):
        group_job = RequestHardwareProfileJob()

    def _create_hardware_for_ou(self, ou_name):
        '''
        Given an OrganizativeUnit's name it checks if it contains any
        computer without a hardware inventory. When it's found, a job is
        created to get the hardware to it.
        '''
        ou = web.ctx.orm.query(OrganizativeUnit).filter(
                OrganizativeUnit.name == ou_name).first()

        if not ou:
            return

        for computer in ou.computers:
            if not computer.hardware:
                self._create_hardware_for_computer(computer.id)

    def _create_hardware_for_computer(self, computer_id):
        '''
        Given a computer_id that hasn't a hardware profile, checks if
        is there any job to do it. If not a job is created.
        '''
        if not web.ctx.orm.query(RequestHardwareProfileJob)\
            .filter(Job.computer_id == computer_id).\
            filter(Job.status.in_(['CREATED', 'WAITING', 'SENT', 'INPROGRESS'])).count():
            # If there isn't a same job in progress for the same computer
            # we send
            self.send_job_create_hardware(computer_id)

    def get_action_instances_for_view(self, view_path, args):
        '''
        Reimplementing function to do more things.
        '''
        if view_path == 'navigator.navigator.NavigatorComputer':
            # Getting the computer
            computer_name = args[0]

            orm = web.ctx.orm
            computer = orm.query(Computer).filter(
                    Computer.name == computer_name).first()

            if computer and computer.hardware:
                # If the computer has hardware
                updateprofile = self.actions['updatehardwareprofile']
                viewprofile = self.actions['viewprofile']
                return [
                    ActionInstance(updateprofile,
                        self.fill_url(views.UpdateHardwareView, computer.name)
                    ),
                    ActionInstance(viewprofile,
                        self.fill_url(views.ProfileHardwareView, computer.name)
                    )
                ]

            else:
                self._create_hardware_for_computer(computer.id)

        elif view_path == 'navigator.navigator.NavigatorOrganizativeUnit':
            # Getting the ou name
            ou_name = args[0]
            self._create_hardware_for_ou(ou_name)

        return []
