#!/usr/bin/python
# -*- coding: utf-8 -*-

# (c) 2019, Ansible by Red Hat, inc
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'network'}

DOCUMENTATION = """
---
module: frr_facts
version_added: "2.8"
author: "Nilashish Chakraborty (@NilashishC)"
short_description: Collect facts from remote devices running Free Range Routing (FRR).
description:
  - Collects a base set of device facts from a remote device that
    is running FRR.  This module prepends all of the
    base network fact keys with C(ansible_net_<fact>).  The facts
    module will always collect a base set of facts from the device
    and can enable or disable collection of additional facts.
notes:
  - Tested against FRR 6.0.
options:
  gather_subset:
    description:
      - When supplied, this argument restricts the facts collected
         to a given subset.
      - Possible values for this argument include
         C(all), C(hardware), C(config), and C(interfaces).
      - Specify a list of values to include a larger subset.
      - Use a value with an initial C(!) to collect all facts except that subset.
    required: false
    default: '!config'
"""

EXAMPLES = """
- name: Collect all facts from the device
  frr_facts:
    gather_subset: all

- name: Collect only the config and default facts
  frr_facts:
    gather_subset:
      - config

- name: Collect the config and hardware facts
  frr_facts:
    gather_subset:
      - config
      - hardware

- name: Do not collect hardware facts
  frr_facts:
    gather_subset:
      - "!hardware"
"""

RETURN = """
ansible_net_gather_subset:
  description: The list of fact subsets collected from the device
  returned: always
  type: list

# default
ansible_net_hostname:
  description: The configured hostname of the device
  returned: always
  type: str
ansible_net_version:
  description: The FRR version running on the remote device
  returned: always
  type: str
ansible_net_api:
  description: The name of the transport
  returned: always
  type: str
ansible_net_python_version:
  description: The Python version that the Ansible controller is using
  returned: always
  type: str

# hardware
ansible_net_mem_stats:
  description: The memory statistics fetched from the device
  returned: when hardware is configured
  type: dict

# config
ansible_net_config:
  description: The current active config from the device
  returned: when config is configured
  type: str

# interfaces
ansible_net_all_ipv4_addresses:
  description: All IPv4 addresses configured on the device
  returned: when interfaces is configured
  type: list
ansible_net_all_ipv6_addresses:
  description: All IPv6 addresses configured on the device
  returned: when interfaces is configured
  type: list
ansible_net_interfaces:
  description: A hash of all interfaces running on the system
  returned: when interfaces is configured
  type: dict
ansible_net_mpls_ldp_neighbors:
  description: The list of MPLS LDP neighbors from the remote device
  returned: when interfaces is configured and LDP daemon is running on the device
  type: dict
"""

import platform
import re

from ansible.module_utils.network.frr.frr import run_commands, get_capabilities
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems


class FactsBase(object):

    COMMANDS = list()

    def __init__(self, module):
        self.module = module
        self.facts = dict()
        self.responses = None
        self._capabilities = get_capabilities(self.module)

    def populate(self):
        self.responses = run_commands(self.module, commands=self.COMMANDS, check_rc=False)

    def run(self, cmd):
        return run_commands(commands=cmd, check_rc=False)

    def parse_facts(self, pattern, data):
        value = None
        match = re.search(pattern, data, re.M)
        if match: