
from django.shortcuts import render_to_response
from django.http import HttpResponse, Http404
from django.template import RequestContext
from paramiko import SSHClient, AutoAddPolicy
from models import *
from WebDash.views import index2

"""Views for DomainMan application
Starts and stops nodeBooter/naming service through paramiko
"""

"""
Testing login
"""
def cornet_login(request):
    user = request.user
    return render_to_response('DomainMan/cornet_login.html', locals(), context_instance=RequestContext(request))

"""
Connects to a server through a given ip, port and associated username and password 
Returns the SSHClient connected to the server
"""
def connect(ip, port, user, password):
    client = SSHClient()
    client.set_missing_host_key_policy(AutoAddPolicy())
    try:
        client.connect(ip, int(port), user, password)
    except:
        raise Http404(u'Incorrect username and password combination')
    return client

'''
Tests if nodebooter is running.
@param client: The SSHClient connected to a server/node
@return: A boolean indicating if nodebooter is running
'''
def nodeBooter_running(client):
    stdin, stdout, stderr = client.exec_command('ps -aux | grep GPP')
    processes = stdout.readlines()
    
    #processes = processes.split()
    
    for proc in processes:
        #print 'proc: ' + str(proc)
        #if '/usr/local/bin/nodeBooter' in proc or '/usr/bin/nodeBooter' in proc or 'nodeBooter' in proc:
        if 'dev/bin/GPP' in proc:
            return 1
    #print 'runningNodebooter: ' + str(runningNodebooter)
#    runningNodebooter = 'dev/nodes/' in processes
    return 0

'''
Starts nodeBooter at a given ip and port
@param ip: The ip address of the server for the nodes
@param port: The port, typically 22
@param user: The user's username with access to the node
@param password: The user's password
'''
def startNodebooter(request, floor, num, user, password):
    floor = int(floor)
    num = int(num)
    node = Node(floor, num)
    ip = node.ip
    port = node.port
    client = connect(ip, port, user, password)
    #stdin, stdout, stderr = client.exec_command('cd /sdr; nodeBooter -D -d dev/nodes/default_GPP_node/DeviceManager.dcd.xml')
    client.exec_command('cd /sdr ; nodeBooter -D -d dev/nodes/default_GPP_node/DeviceManager.dcd.xml')
    runningNodebooter = nodeBooter_running(client)
    return render_to_response('DomainMan/runningNodebooter.html', locals(), context_instance=RequestContext(request))

"""Start nodebooter with premade client from client list
"""
#def startNodebooter(request, floor, number):
#    clientID = str(postFloor).__add__("-").__add__(str(postNum))
#    client = SSHClientList.getClient(clientID)
#    #stdin, stdout, stderr = client.exec_command('cd /sdr; nodeBooter -D -d dev/nodes/default_GPP_node/DeviceManager.dcd.xml')
#    client.exec_command('cd /sdr; nodeBooter -D -d dev/nodes/default_GPP_node/DeviceManager.dcd.xml')
#    runningNodebooter = nodeBooter_running(client)
#    return render_to_response('DomainMan/runningNodebooter.html', locals(), context_instance=RequestContext(request))

'''
Kills all nodeBooter processes at a given ip and port
@param ip: The ip address of the server for the nodes
@param port: The port, typically 22
@param user: The user's username with access to the node
@param password: The user's password
'''
def stopNodebooter(request, floor, num, user, password):
    floor = int(floor)
    num = int(num)
    node = Node(floor, num)
    ip = node.ip
    port = node.port
    client = connect(ip, port, user, password)
    stdin, stdout, stderr = client.exec_command('killall nodeBooter && killall GPP')
    runningNodebooter = nodeBooter_running(client)
    return render_to_response('DomainMan/runningNodebooter.html', locals(), context_instance=RequestContext(request))

'''
Testing view to check if nodebooter is running.
Checks if nodeBooter is running, if not, starts it.
@param ip: The ip address of the server for the nodes
@param port: The port, typically 22
@param user: The user's username with access to the node
@param password: The user's password
'''
def nodeBooter_page(request, ip, port, user, password):
    if 'ip' in request.POST and 'port' in request.POST and 'user' in request.POST and 'pass' in request.POST:
        client = connect(ip, port, user, password)
    else:
        raise Exception('client could not connect with POST variables')
    if not nodeBooter_running(client):
        stdin, stdout, stderr = client.exec_command('cd /sdr; nodeBooter -D -d dev/nodes/default_GPP_node/DeviceManager.dcd.xml')
    runningNodebooter = nodeBooter_running(client)
    return render_to_response('DomainMan/console.html', locals(), context_instance=RequestContext(request))

"""
Views the available nodeBooters to start
"""
def selectNodeboter():
    return

"""
Connect to a node through a form
"""
def connect_to_node(request):
    if 'floor' in request.POST and 'number' in request.POST and 'user' in request.POST and 'pass' in request.POST:
        floor = int(request.POST['floor'])
        num = int(request.POST['number'])
        user = str(request.POST['user'])
        password = str(request.POST['pass'])
        
        node = Node(floor, num)
        ip = node.ip
        port = node.port
        client = connect(ip, port, user, password)
        runningNodebooter = nodeBooter_running(client)
    else:
        message = 'Missing ssh connection parameters'
        print message
    return render_to_response('DomainMan/runningNodebooter.html', locals(), context_instance=RequestContext(request))

"""
Raise exception if the inputs of the floor and node number are invalid
"""
def testValidInputs(floor, num):
    if floor < 1 or floor > 4:
        raise Exception("Floor must be between 1 and 4")
    if num < 1 or num > 12:
        raise Exception("Node must be between 1 and 12")

#@login_required
def loadNode(request, floor_num, node_num):
    floor = int(floor_num)
    num = int(node_num)
    testValidInputs(floor, num)
    node = Node(floor, num)
    ip = node.ip
    port = node.port
    #index2(request, ip)
    return render_to_response("DomainMan/nodes.html", locals(), context_instance=RequestContext(request))

"""
Returns connection form
"""
def connect_to_node_view(request, selectFloor, selectNum):
    number_of_floors = range(1,5)
    number_of_nodes = range(1,13)
    selectedFloor=int(selectFloor)
    selectedNum=int(selectNum)
    testValidInputs(selectedFloor, selectedNum)
    return render_to_response('DomainMan/connect.html', locals(), RequestContext(request))

def ajax_example(request):
    if not request.method == 'GET':
        name = "did not work"
        print request.GET
        return render_to_response('DomainMan/ajax_example.html', locals(), context_instance=RequestContext(request))
    response_dict = {}
    name = request.GET.get('name', False)
    total = request.GET.get('total', False)
    response_dict.update({'name': name, 'total': total})
    if total:
        try:
            total = int(total)
        except:
            total = False
    if name and total and int(total) == 10:
        response_dict.update({'success': True })
    else:
        response_dict.update({'errors': {}})
        if not name:
            response_dict['errors'].update({'name': 'This field is required'})
        if not total and total is not False:
            response_dict['errors'].update({'total': 'This field is required'})
        elif int(total) != 10:
            response_dict['errors'].update({'total': 'Incorrect total'})
    return render_to_response('DomainMan/ajax_example.html', response_dict, context_instance=RequestContext(request))
