#
# (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
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.providers import (
    providers,
)
from ansible.module_utils._text import to_text


class NetworkModule(AnsibleModule):

    fail_on_missing_provider = True

    def __init__(self, connection=None, *args, **kwargs):
        super(NetworkModule, self).__init__(*args, **kwargs)

        if connection is None:
            connection = Connection(self._socket_path)

        self.connection = connection

    @property
    def provider(self):
        if not hasattr(self, "_provider"):
            capabilities = self.from_json(self.connection.get_capabilities())

            network_os = capabilities["device_info"]["network_os"]
            network_api = capabilities["network_api"]

            if network_api == "cliconf":
                connection_type = "network_cli"

            cls = providers.get(
                network_os, self._name.split(".")[-1], connection_type
            )

            if not cls:
                msg = (
                    "unable to find suitable provider for network os %s"
                    % network_os
                )
                if self.fail_on_missing_provider:
                    self.fail_json(msg=msg)
                else:
                    self.warn(msg)

            obj = cls(self.params, self.connection, self.check_mode)

            setattr(self, "_provider", obj)

        return getattr(self, "_provider")

    def get_facts(self, subset=None):
        try:
            self.provider.get_facts(subset)
        except Exception as exc:
            self.fail_json(msg=to_text(exc))

    def edit_config(self, config_filter=None):
        current_config = self.connection.get_config(flags=config_filter)
        try:
            commands = self.provider.edit_config(current_config)
            changed = bool(commands)
            return {"commands": commands, "changed": changed}
        except Exception as exc:
            self.fail_json(msg=to_text(exc))
