# -*- coding: utf-8 -*-

##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openvim
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##

'''
This is thread that interact with the dhcp server to get the IP addresses 
'''
__author__="Pablo Montes, Alfonso Tierno"
__date__ ="$4-Jan-2016 12:07:15$"



import threading
import time
import Queue
import paramiko
import random
import subprocess
import logging

#TODO: insert a logging system

class dhcp_thread(threading.Thread):
    def __init__(self, dhcp_params, db, db_lock, test, dhcp_nets, logger_name=None, debug=None):
        '''Init a thread.
        Arguments: thread_info must be a dictionary with:
            'dhcp_params' dhcp server parameters with the following keys:
                mandatory : user, host, port, key, ifaces(interface name list of the one managed by the dhcp)
                optional:  password, key, port(22)
            'db' 'db_lock': database class and lock for accessing it
            'test': in test mode no acces to a server is done, and ip is invented
        '''
        threading.Thread.__init__(self)
        self.dhcp_params = dhcp_params
        self.db = db
        self.db_lock = db_lock
        self.test = test
        self.dhcp_nets = dhcp_nets
        self.ssh_conn = None
        if logger_name:
            self.logger_name = logger_name
        else:
            self.logger_name = "openvim.dhcp"
        self.logger = logging.getLogger(self.logger_name)
        if debug:
            self.logger.setLevel(getattr(logging, debug))

        self.mac_status ={} #dictionary of mac_address to retrieve information
            #ip: None
            #retries: 
            #next_reading: time for the next trying to check ACTIVE status or IP
            #created: time when it was added 
            #active: time when the VM becomes into ACTIVE status
            
        
        self.queueLock = threading.Lock()
        self.taskQueue = Queue.Queue(2000)
        
    def ssh_connect(self):
        try:
            #Connect SSH
            self.ssh_conn = paramiko.SSHClient()
            self.ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh_conn.load_system_host_keys()
            self.ssh_conn.connect(self.dhcp_params["host"], port=self.dhcp_params.get("port", 22),
                                  username=self.dhcp_params["user"], password=self.dhcp_params.get("password"),
                                  key_filename=self.dhcp_params.get("key"), timeout=2)
        except paramiko.ssh_exception.SSHException as e:
            self.logger.error("ssh_connect ssh Exception " + str(e))
        
    def load_mac_from_db(self):
        #TODO get macs to follow from the database
        self.logger.debug("load macs from db")
        self.db_lock.acquire()
        r,c = self.db.get_table(SELECT=('mac','ip_address','nets.uuid as net_id', ),
                                FROM='ports join nets on ports.net_id=nets.uuid', 
                                WHERE_NOT={'ports.instance_id': None, 'nets.provider': None})
        self.db_lock.release()
        now = time.time()
        self.mac_status ={}
        if r<0:
            self.logger.error("Error getting data from database: " + c)
            return
        for port in c:
            if port["net_id"] in self.dhcp_nets:
                self.mac_status[ port["mac"] ] = {"ip": port["ip_address"], "next_reading": now, "created": now, "retries":0}
    
    def insert_task(self, task, *aditional):
        try:
            self.queueLock.acquire()
            task = self.taskQueue.put( (task,) + aditional, timeout=5) 
            self.queueLock.release()
            return 1, None
        except Queue.Full:
            return -1, "timeout inserting a task over dhcp_thread"

    def run(self):
        self.logger.debug("starting, nets: " + str(self.dhcp_nets))
        next_iteration = time.time() + 10
        while True:
            self.load_mac_from_db()
            while True:
                try:
                    self.queueLock.acquire()
                    if not self.taskQueue.empty():
                        task = self.taskQueue.get()
                    else:
                        task = None
                    self.queueLock.release()

                    if task is None:
                        now=time.time()
                        if now >= next_iteration:
                            next_iteration = self.get_ip_from_dhcp()
                        else:
                            time.sleep(1)
                        continue

                    if task[0] == 'add':
                        self.logger.debug("processing task add mac " + str(task[1]))
                        now=time.time()
                        self.mac_status[task[1] ] = {"ip": None, "next_reading": now, "created": now, "retries":0}
                        next_iteration = now
                    elif task[0] == 'del':
                        self.logger.debug("processing task del mac " + str(task[1]))
                        if task[1] in self.mac_status:
                            del self.mac_status[task[1] ]
                    elif task[0] == 'exit':
                        self.logger.debug("processing task exit")
                        self.terminate()
                        return 0
                    else:
                        self.logger.error("unknown task: " + str(task))
                except Exception as e:
                    self.logger.critical("Unexpected exception at run: " + str(e), exc_info=True)
          
    def terminate(self):
        try:
            if self.ssh_conn:
                self.ssh_conn.close()
        except Exception as e:
            self.logger.error("terminate Exception: " + str(e))
        self.logger.debug("exit from dhcp_thread")

    def get_ip_from_dhcp(self):
        
        now = time.time()
        next_iteration= now + 40000 # >10 hores
        
        #print self.name, "Iteration" 
        for mac_address in self.mac_status:
            if now < self.mac_status[mac_address]["next_reading"]:
                if self.mac_status[mac_address]["next_reading"] < next_iteration:
                    next_iteration = self.mac_status[mac_address]["next_reading"]
                continue
            
            if self.mac_status[mac_address].get("active") == None:
                #check from db if already active
                self.db_lock.acquire()
                r,c = self.db.get_table(FROM="ports as p join instances as i on p.instance_id=i.uuid",
                                        WHERE={"p.mac": mac_address, "i.status": "ACTIVE"})
                self.db_lock.release()
                if r>0:
                    self.mac_status[mac_address]["active"] = now
                    self.mac_status[mac_address]["next_reading"] = (int(now)/2 +1)* 2
                    self.logger.debug("mac %s VM ACTIVE", mac_address)
                    self.mac_status[mac_address]["retries"] = 0
                else:
                    #print self.name, "mac %s  VM INACTIVE" % (mac_address)
                    if now - self.mac_status[mac_address]["created"] > 300:
                        #modify Database to tell openmano that we can not get dhcp from the machine
                        if not self.mac_status[mac_address].get("ip"):
                            self.db_lock.acquire()
                            r,c = self.db.update_rows("ports", {"ip_address": "0.0.0.0"}, {"mac": mac_address})
                            self.db_lock.release()
                            self.mac_status[mac_address]["ip"] = "0.0.0.0"
                            self.logger.debug("mac %s >> set to 0.0.0.0 because of timeout", mac_address)
                        self.mac_status[mac_address]["next_reading"] = (int(now)/60 +1)* 60
                    else:
                        self.mac_status[mac_address]["next_reading"] = (int(now)/6 +1)* 6
                if self.mac_status[mac_address]["next_reading"] < next_iteration:
                    next_iteration = self.mac_status[mac_address]["next_reading"]
                continue
            

            if self.test:
                if self.mac_status[mac_address]["retries"]>random.randint(10,100): #wait between 10 and 100 seconds to produce a fake IP
                    content = self.get_fake_ip()
                else:
                    content = None
            elif self.dhcp_params["host"]=="localhost":
                try:
                    command = ['get_dhcp_lease.sh',  mac_address]
                    content = subprocess.check_output(command)
                except Exception as e:
                    self.logger.error("get_ip_from_dhcp subprocess Exception " + str(e))
                    content = None
            else:
                try:
                    if not self.ssh_conn:
                        self.ssh_connect()
                    command = 'get_dhcp_lease.sh ' +  mac_address
                    (_, stdout, _) = self.ssh_conn.exec_command(command)
                    content = stdout.read()
                except paramiko.ssh_exception.SSHException as e:
                    self.logger.error("get_ip_from_dhcp: ssh_Exception: " + srt(e))
                    content = None
                    self.ssh_conn = None
                except Exception as e:
                    self.logger.error("get_ip_from_dhcp: Exception: " + str(e))
                    content = None
                    self.ssh_conn = None

            if content:
                self.mac_status[mac_address]["ip"] = content
                #modify Database
                self.db_lock.acquire()
                r,c = self.db.update_rows("ports", {"ip_address": content}, {"mac": mac_address})
                self.db_lock.release()
                if r<0:
                    self.logger.error("Database update error: " + c)
                else:
                    self.mac_status[mac_address]["retries"] = 0
                    self.mac_status[mac_address]["next_reading"] = (int(now)/3600 +1)* 36000 # 10 hores
                    if self.mac_status[mac_address]["next_reading"] < next_iteration:
                        next_iteration = self.mac_status[mac_address]["next_reading"]
                    self.logger.debug("mac %s >> %s", mac_address, content)
                    continue
            #a fail has happen
            self.mac_status[mac_address]["retries"] +=1
            #next iteration is every 2sec at the beginning; every 5sec after a minute, every 1min after a 5min
            if now - self.mac_status[mac_address]["active"] > 120:
                #modify Database to tell openmano that we can not get dhcp from the machine
                if not self.mac_status[mac_address].get("ip"):
                    self.db_lock.acquire()
                    r,c = self.db.update_rows("ports", {"ip_address": "0.0.0.0"}, {"mac": mac_address})
                    self.db_lock.release()
                    self.mac_status[mac_address]["ip"] = "0.0.0.0"
                    self.logger.debug("mac %s >> set to 0.0.0.0 because of timeout", mac_address)
            
            if now - self.mac_status[mac_address]["active"] > 60:
                self.mac_status[mac_address]["next_reading"] = (int(now)/6 +1)* 6
            elif now - self.mac_status[mac_address]["active"] > 300:
                self.mac_status[mac_address]["next_reading"] = (int(now)/60 +1)* 60
            else:
                self.mac_status[mac_address]["next_reading"] = (int(now)/2 +1)* 2
                
            if self.mac_status[mac_address]["next_reading"] < next_iteration:
                next_iteration = self.mac_status[mac_address]["next_reading"]
        return next_iteration    
    
    def get_fake_ip(self):
        fake_ip = "192.168.{}.{}".format(random.randint(1,254), random.randint(1,254) )
        while True:
            #check not already provided
            already_used = False
            for mac_address in self.mac_status:
                if self.mac_status[mac_address]["ip"] == fake_ip:
                    already_used = True
                    break
            if not already_used:
                return fake_ip


#EXAMPLE of bash script that must be available at the DHCP server for "isc-dhcp-server" type
#     $ cat ./get_dhcp_lease.sh
#     #!/bin/bash
#     awk '
#     ($1=="lease" && $3=="{"){ lease=$2; active="no"; found="no" }
#     ($1=="binding" && $2=="state" && $3=="active;"){ active="yes" }
#     ($1=="hardware" && $2=="ethernet" && $3==tolower("'$1';")){ found="yes" }
#     ($1=="client-hostname"){ name=$2 }
#     ($1=="}"){ if (active=="yes" && found=="yes"){ target_lease=lease; target_name=name}}
#     END{printf("%s", target_lease)} #print target_name
#     ' /var/lib/dhcp/dhcpd.leases

 
