#!/usr/bin/env python

import os
import re
import json
from data import variables
from collections import OrderedDict

bmc_rec_pattern = '^=(.*)\n(.*)\n(.*)\n(.*)\n(.*)'
bmc_prop_pattern = [r"\w+", r"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}", '443']
bmc_rec_prop = ['hostname', 'address', 'port', 'txt']


class Exception(Exception):
    def __init__(self, exc_value):
        self.exc_value = exc_value

    def __str__(self):
        return repr(self.exc_value)


def Check_bmc_record_exists(bmc_records, bmc_ip):
    r"""
    Parse the BMC records to check for passed input.

    Description of arguments:
    bmc_records            Contains the list of discoverd BMC records.
    bmc_ip                 BMC ip address.
    """

    try:
        for bmc_key, bmc_val in bmc_records.items():
            temp_ip = bmc_val.get('address', None)
            if bmc_ip.strip() == temp_ip.strip():
                return True
        else:
            return False
    except Exception as exc_obj:
        return exc_obj


def validate_bmc_properties(bmc_prop_pattern, bmc_prop, bmc_value,
                            bmc_rec_valid):
    r"""
    This function is to check pattern match in bmc properties.

    Description of arguments:
    bmc_prop_pattern       Regex pattern.
    bmc_prop               BMC property (e.g. hostname, address, port).
    bmc_value              BMC property value.
    bmc_rec_valid          Contain BMC properties record.
    """

    try:
        status = \
            [lambda bmc_prop: re.search(bmc_prop_pattern, bmc_prob),
                bmc_value]
        if None in status:
            bmc_rec_valid[bmc_prop] = None
    except Exception as exc_obj:
        return exc_obj
    finally:
        return bmc_rec_valid


def bmc_record_validation(bmc_rec_valid):
    r"""
    Parse the BMC records to validate the data is valid.

    Description of arguments:
    bmc_rec_valid          Contain BMC properties record.
    """

    try:
        for bmc_prop_key, bmc_pattern_val in \
                zip(bmc_rec_prop, bmc_prop_pattern):
            bmc_prop_value = bmc_rec_valid.get(bmc_prop_key, False)
            if bmc_rec_valid[bmc_prop_key] is not False:
                valid_status = validate_bmc_properties(bmc_pattern_val,
                                                       bmc_prop_key,
                                                       bmc_prop_value,
                                                       bmc_rec_valid)
                if None not in bmc_rec_valid.values():
                    return bmc_rec_valid
                else:
                    return None
    except Exception as exc_obj:
        return exc_obj


def bmc_inventory(service_type, bmc_inv_record):
    r"""
    Parse single record of BMC inventory and pack to dictionary form.

    Description of arguments:
    service_type       Service type (e.g. _obmc_rest._tcp, _obmc_redfish._tcp).
    bmc_inv_record     Individual BMC inventory record.

    This function will return this variable i.e.
    bmc_inv in dictionary form as mention below.

    Below are the discovered BMC detail.

    [service]:          _obmc_XXXX._tcp
    [hostname]:         System Name
    [address]:          XXX.XXX.XXX.XXX
    [port]:             XXX
    [txt]:
    """

    try:
        exc_obj = None
        bmc_inv = OrderedDict()
        service_count = 0
        for line in bmc_inv_record.split('\n'):
            if line == "":
                pass
            elif service_type in line:
                bmc_inv['service'] = service_type
                service_count += 1
            elif not line.startswith('=') and service_count == 1:
                bmc_inv[line.split('=')[0].strip()] = \
                    str(line.split('=')[-1].strip())[1:-1]
    except Exception as exc_obj:
        return exc_obj
    finally:
        valid_status = bmc_record_validation(bmc_inv)
        if valid_status is None:
            return None, exc_obj
        else:
            return valid_status, exc_obj


def get_bmc_records(service_type, bmc_records):
    r"""
    Parse the string to filter BMC discovery.

    Description of arguments:
    service_type     Service type (e.g. RESTService, RedfishService).
    bmc_records      Contains the list of discoverd BMC records.

    This function will return this variable i.e.
    bmc_inv_list in dictionary form as mention below.

    Below are the list of discovered BMC details.
    [1]:
        [service]:          _obmc_XXXX._tcp
        [hostname]:         System Name
        [address]:          XXX.XXX.XXX.XXX
        [port]:             XXX
        [txt]:
    [2]:
        [service]:          _obmc_XXXX._tcp
        [hostname]:         System Name
        [address]:          XXX.XXX.XXX.XXX
        [port]:             XXX
        [txt]:
    """

    try:
        count = 0
        exe_obj = None
        bmc_inv_list = OrderedDict()
        for match in re.finditer(bmc_rec_pattern, bmc_records,
                                 re.MULTILINE):
            bmc_record, exc_msg = \
                bmc_inventory(service_type, match.group())
            if bmc_record is not None and exc_msg is None:
                count += 1
                bmc_inv_list[count] = bmc_record
    except Exception as exe_obj:
        return exe_obj
    finally:
        if len(bmc_inv_list) == 0:
            '', exe_obj
        else:
            return bmc_inv_list, exe_obj
