# Functions to insert data into database
#

# Imports
import os, re, datetime, urllib, sys, json

# To import debsecan conf
from ivulncheck_api.lib.config_api import Configuration as conf

import logging
logging.basicConfig(filename=conf.getLogfile(), level=logging.INFO)

from ivulncheck_api.lib import cvesearch_api_layer as cveapi
from ivulncheck_api.lib import Vulns
from ivulncheck_api.lib import functions as f

from ivulncheck_api.lib import debsecan_layer as dsal
    
def insert_host(db, data):

    hostname = data['hostname']
    ipv4 = data['ipv4']
    os_family = data['osfamily']
    os_type = data['ostype']
    os_version = data['osversion']
    
    try:
        suite_name = data['suitename']
    except IndexError:
        suite_name = None
    
    results = db.purgeHost(hostname)
    flag=True
    for result in results:
        if result.acknowledged == False:
            flag=False
    if flag == True:
        logging.info('[%s] (%s)\tHost %s successfuly purged.', datetime.datetime.today().isoformat(), __name__, hostname)
    else:
        logging.info('[%s] (%s)\tA problem occured when purging host %s.', datetime.datetime.today().isoformat(), __name__, hostname)
    
    pkgs = []
    prods = []
    
    nb_mod_pkg2cpe = 0
    nb_err_pkg2cpe = 0
    
    fixes = []
   
    for pkg_line in data['packages']:
        
        hosts = []
        hosts.append(hostname)
        
        try:
            pkgs.append(Vulns.Package(hosts, pkg_line['pkg_name'], pkg_line['pkg_vers'], pkg_line['src_name'], pkg_line['src_vers'], None, None, os_type, suite_name))
        except KeyError as ke:
            # First search in index
            cpe_id = db.getPkg2CPE(pkg_line['prod_name'])
            if cpe_id is None:
                # Then search CVESearch
                
                (status, cpe_id) = cveapi.findCPEid(pkg_line['prod_name'] + ":" + pkg_line['prod_vers'])
                if status == False:
                    # Insert index with "empty" for faster search
                    result_pkg2cpe = db.insertPkg2CPE({'id': pkg_line['prod_name'], 'cpeid': "empty"})
                    if result_pkg2cpe == True:
                        nb_mod_pkg2cpe += 1
                    else:
                        nb_err_pkg2cpe += 1
                else:
                    # Insert index with cpeid
                    result_pkg2cpe = db.insertPkg2CPE({'id': pkg_line['prod_name'], 'cpeid': cpe_id})
                    if result_pkg2cpe == True:
                        nb_mod_pkg2cpe += 1
                    else:
                        nb_err_pkg2cpe += 1
            elif cpe_id == "empty":
                cpe_id = None
            #logging.info('[%s] (%s)\t %s .', datetime.datetime.today().isoformat(), __name__, cpe_id)
            prods.append(Vulns.Product(hosts, pkg_line['prod_name'], pkg_line['prod_vers'], cpe_id))

    nb_mod_pkg = 0
    nb_err_pkg = 0
    nb_mod_prod = 0
    nb_err_prod = 0
    nb_mod_fix = 0
    nb_err_fix = 0
    
    for pkg in pkgs:
        result_pkg = db.insertPackage(pkg.to_json())
        
        if result_pkg == True:
            nb_mod_pkg += 1
        else:
            nb_err_pkg += 1
            
    for prod in prods:
        result_prod = db.insertProduct(prod.to_json())
        
        if result_prod == True:
            nb_mod_prod += 1
        else:
            nb_err_prod += 1

    resulthost = db.insertHost(Vulns.Host(hostname, os_type, suite_name, ipv4, datetime.datetime.today().isoformat()).to_json())
    if resulthost == True:
        logging.info('[%s] (%s)\tHost : %s inserted.', datetime.datetime.today().isoformat(), __name__, hostname)
    else:
        logging.error('[%s] (%s)\tHost : %s not inserted.', datetime.datetime.today().isoformat(), __name__, hostname)
    
    logging.info('[%s] (%s)\t%d package(s) linked to Host : %s inserted in HostDB and %d errors.', datetime.datetime.today().isoformat(), __name__, nb_mod_pkg, hostname, nb_err_pkg)
    logging.info('[%s] (%s)\t%d product(s) linked to Host : %s inserted in HostDB and %d errors.', datetime.datetime.today().isoformat(), __name__, nb_mod_prod, hostname, nb_err_prod)
    
    return resulthost, nb_mod_pkg, nb_err_pkg, nb_mod_fix, nb_err_fix
