#!/usr/bin/env python

from common import config
from common.entities import entities
from common import oids
from common.prettytable import PrettyTable
from common.util import cisco_tics_to_ctime
from common.util import send_email
from common.util import get_snmp_data
from common.util import myDict
from common.util import read_data_file
from common.util import write_data_file
import os
import time


def my_oids():
    oids_dict = {
        'running_last_changed': oids.get('ccmHistoryRunningLastChanged'),
        'running_last_saved': oids.get('ccmHistoryRunningLastSaved'),
        'startup_last_changed': oids.get('ccmHistoryStartupLastChanged'),
        'uptime': oids.get('sysUptime'),
    }
    return myDict(oids_dict)


def my_data_files():
    data_folder = config.cfg.data_file_folder
    data_files = ['last_changed.p', 'last_changed.json', 'last_changed.yml']
    full_file_paths = []
    for data_file in data_files:
        file_name = '/'.join([data_folder, data_file])
        full_file_paths.append(file_name)
    return full_file_paths


def is_equal_dicts(data_dict):
    d_list = []
    for data in data_dict.itervalues():
        d_list.append(data)

    if d_list.count(d_list[0]) == len(d_list):
        return True
    else:
        return False


def my_get_snmp_data(device_tuple, user_tuple, oids_dict):
    snmp_data_dict = myDict()
    snmp_data_dict['epoch'] = str(time.time())
    for oid_alias, oid_string in oids_dict.items():
        snmp_data_dict[oid_alias] = get_snmp_data(
            tuple(device_tuple),
            tuple(user_tuple),
            oid_string
        )
    return dict(snmp_data_dict)


def get_file_data(file_name):
    file_data_dict = read_data_file(file_name)
    return file_data_dict


def write_data(file_name, data):
    write_data_file(file_name, data)


def setup():
    setup_args = myDict()
    setup_args.devices = entities.devices
    setup_args.user_tuple = entities.users.user1
    setup_args.oids_dict = my_oids()
    setup_args.data_files = my_data_files()
    setup_args.file_data_dict = myDict()
    return setup_args


def get_device_data(data_files):
    # Load saved device data if any, from all indicated data files.
    # There are multiple data files just to illustrate the use of
    # various data formats (JSON, YAML, PICKLE).
    # Make sure the data structure is the same in each data file.
    saved_data = myDict()
    saved_devices = myDict()
    for file_name in data_files:
        saved_data[file_name] = get_file_data(file_name)
    if is_equal_dicts(saved_data):
        if saved_data[file_name] is not None:
            saved_devices = saved_data[file_name]
    else:
        print (
            "ERROR: Data in data files differs! Deleting data files.",
            data_files
        )
        for file_name in data_files:
            if os.path.exists(file_name):
                os.remove(file_name)
        raise BaseException
    return saved_data, saved_devices


def get_device_snmp_data(devices, user_tuple, oids_dict):
    # get snmp data from each device for each oid
    snmp_data = myDict()
    for dev_name, device_tuple in devices.iteritems():
        snmp_data[dev_name] = my_get_snmp_data(
            device_tuple,
            user_tuple,
            oids_dict
        )
    return snmp_data


def compare_snmp_saved(snmp_data, saved_devices):
    # compare SNMP data with saved data
    devices_dict = {}
    for dev_name in list([x for x in snmp_data if x in saved_devices]):
        saved = saved_devices[dev_name]
        snmp = snmp_data[dev_name]

        # logic to detect running config changes and reloads
        change_detected = False
        reload_detected = False
        status_msg = ""
        if (
            snmp['uptime'] < saved['uptime'] or
            snmp['running_last_changed'] < saved['running_last_changed']
        ):
            reload_detected = True
            if (
                snmp['running_last_changed'] <=
                config.cfg.reload_max_last_changed
            ):
                status_msg = (
                    dev_name, "was RELOADED, running config NOT CHANGED."
                )
                change_detected = False
            else:
                status_msg = dev_name, "was RELOADED, running config CHANGED."
                change_detected = True
        elif snmp['running_last_changed'] == saved['running_last_changed']:
            status_msg = dev_name, "running config NOT CHANGED."
            change_detected = False
        elif snmp['running_last_changed'] > saved['running_last_changed']:
            status_msg = dev_name, "running config CHANGED."
            change_detected = True
        else: