""" Test output wizards
"""
import unittest
import mock

from ..ansible_runner_svc import EVENT_DATA_URL
from ..output_wizards import ProcessHostsList, ProcessPlaybookResult, \
                             ProcessInventory

class  OutputWizardProcessHostsList(unittest.TestCase):
    """Test ProcessHostsList Output Wizard
    """
    RESULT_OK = """
                {
                "status": "OK",
                "msg": "",
                "data": {
                    "hosts": [
                        "host_a",
                        "host_b",
                        "host_c"
                        ]
                    }
                }
                """
    ar_client = mock.Mock()
    logger = mock.Mock()
    test_wizard = ProcessHostsList(ar_client, logger)

    def test_process(self):
        """Test a normal call"""

        nodes_list = self.test_wizard.process("", self.RESULT_OK)
        self.assertEqual([node.name for node in nodes_list],
                         ["host_a", "host_b", "host_c"])

    def test_errors(self):
        """Test different kind of errors processing result"""

         # Malformed json
        host_list = self.test_wizard.process("", """{"msg": """"")
        self.assertEqual(host_list, [])

        # key error
        host_list = self.test_wizard.process("", """{"msg": ""}""")
        self.assertEqual(host_list, [])

        # Hosts not in iterable
        host_list = self.test_wizard.process("", """{"data":{"hosts": 123} }""")
        self.assertEqual(host_list, [])

class OutputWizardProcessPlaybookResult(unittest.TestCase):
    """Test ProcessPlaybookResult Output Wizard
    """
    # Input to process
    INVENTORY_EVENTS = {1:"first event", 2:"second event"}
    EVENT_INFORMATION = "event information\n"

    # Mocked response
    mocked_response = mock.Mock()
    mocked_response.text = EVENT_INFORMATION

    # The Ansible Runner Service client
    ar_client = mock.Mock()
    ar_client.http_get = mock.MagicMock(return_value=mocked_response)

    logger = mock.Mock()

    test_wizard = ProcessPlaybookResult(ar_client, logger)

    def test_process(self):
        """Test a normal call
        """

        operation_id = 24
        result = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS)

        # Check http request are correct and compose expected result
        expected_result = ""
        for key, dummy_data in self.INVENTORY_EVENTS.items():
            http_request = EVENT_DATA_URL % (operation_id, key)
            self.ar_client.http_get.assert_any_call(http_request)
            expected_result += self.EVENT_INFORMATION

        #Check result
        self.assertEqual(result, expected_result)

class OutputWizardProcessInventory(unittest.TestCase):
    """Test ProcessInventory Output Wizard
    """
    # Input to process
    INVENTORY_EVENTS = {'event_uuid_1': {'host': '192.168.121.144',
                                         'task': 'list storage inventory',
                                         'event': 'runner_on_ok'}}
    EVENT_DATA = r"""
    {
    "status": "OK",
    "msg": "",
    "data": {
        "uuid": "5e96d509-174d-4f5f-bd94-e278c3a5b85b",
        "counter": 11,
        "stdout": "changed: [192.168.121.144]",
        "start_line": 17,
        "end_line": 18,
        "runner_ident": "6e98b2ba-3ce1-11e9-be81-2016b900e38f",
        "created": "2019-03-02T11:50:56.582112",
        "pid": 482,
        "event_data": {
            "play_pattern": "osds",
            "play": "query each host for storage device inventory",
            "task": "list storage inventory",
            "task_args": "_ansible_version=2.6.5, _ansible_selinux_special_fs=['fuse', 'nfs', 'vboxsf', 'ramfs', '9p'], _ansible_no_log=False, _ansible_module_name=ceph_volume, _ansible_debug=False, _ansible_verbosity=0, _ansible_keep_remote_files=False, _ansible_syslog_facility=LOG_USER, _ansible_socket=None, action=inventory, _ansible_diff=False, _ansible_remote_tmp=~/.ansible/tmp, _ansible_shell_executable=/bin/sh, _ansible_check_mode=False, _ansible_tmpdir=None",
            "remote_addr": "192.168.121.144",
            "res": {
                "_ansible_parsed": true,
                "stderr_lines": [],
                "changed": true,
                "end": "2019-03-02 11:50:56.554937",
                "_ansible_no_log": false,
                "stdout": "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]",
                "cmd": [
                    "ceph-volume",
                    "inventory",
                    "--format=json"
                ],
                "rc": 0,
                "start": "2019-03-02 11:50:55.150121",
                "stderr": "",
                "delta": "0:00:01.404816",
                "invocation": {
                    "module_args": {
                        "wal_vg": null,
                        "wal": null,
                        "dmcrypt": false,
                        "block_db_size": "-1",
                        "journal": null,
                        "objectstore": "bluestore",
                        "db": null,
                        "batch_devices": [],
                        "db_vg": null,
                        "journal_vg": null,
                        "cluster": "ceph",
                        "osds_per_device": 1,
                        "containerized": "False",
                        "crush_device_class": null,
                        "report": false,
                        "data_vg": null,
                        "data": null,
                        "action": "inventory",
                        "journal_size": "5120"
                    }
                },
                "stdout_lines": [
                    "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]"
                ]
            },
            "pid": 482,
            "play_uuid": "2016b900-e38f-0e09-19be-00000000000c",
            "task_uuid": "2016b900-e38f-0e09-19be-000000000012",
            "event_loop": null,
            "playbook_uuid": "e80e66f2-4a78-4a96-aaf6-fbe473f11312",
            "playbook": "storage-inventory.yml",
            "task_action": "ceph_volume",
            "host": "192.168.121.144",
            "task_path": "/usr/share/ansible-runner-service/project/storage-inventory.yml:29"
        },
        "event": "runner_on_ok"
    }
    }
    """

    # Mocked response
    mocked_response = mock.Mock()
    mocked_response.text = EVENT_DATA

    # The Ansible Runner Service client
    ar_client = mock.Mock()
    ar_client.http_get = mock.MagicMock(return_value=mocked_response)

    logger = mock.Mock()

    test_wizard = ProcessInventory(ar_client, logger)

    def test_process(self):
        """Test a normal call
        """
        operation_id = 12
        nodes_list = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS)

        for key, dummy_data in self.INVENTORY_EVENTS.items():
            http_request = EVENT_DATA_URL % (operation_id, key)
            self.ar_client.http_get.assert_any_call(http_request)


        # Only one host
        self.assertTrue(len(nodes_list), 1)

        # Host retrieved OK
        self.assertEqual(nodes_list[0].name, "192.168.121.144")

        # Devices
        self.assertTrue(len(nodes_list[0].devices), 4)

        expected_device_ids = ["/dev/sdc", "/dev/sda", "/dev/sdb", "/dev/vda"]
        device_ids = [dev.id for dev in nodes_list[0].devices]

        self.assertEqual(expected_device_ids, device_ids)
