#!/usr/bin/env python3

import json
import os
import re
from collections import OrderedDict

from data import variables

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
