""" Test class for agents
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# pylint: disable=protected-access, missing-docstring, invalid-name, line-too-long

import pytest
from mock import MagicMock

from DIRAC import gLogger
# sut
from DIRAC.ResourceStatusSystem.Agent.SummarizeLogsAgent import SummarizeLogsAgent

# mocks
rsClientMock = MagicMock()

# useful stuff
sOk = {'OK': True, 'Value': []}
sError = {'OK': False, 'Message': 'a mess'}


columns = ['ID', 'Name', 'StatusType', 'Status', 'ElementType', 'TokenOwner']
el101 = [101, 'RRCKI-BUFFER', 'WriteAccess', 'Active', 'StorageElement', 'rs_svc']
el102 = [102, 'RRCKI-BUFFER', 'WriteAccess', 'Active', 'StorageElement', 'rs_svc']
el103 = [103, 'RRCKI-BUFFER', 'ReadAccess', 'Active', 'StorageElement', 'rs_svc']
el104 = [104, 'RRCKI-BUFFER', 'ReadAccess', 'Active', 'StorageElement', 'rs_svc']
el105 = [105, 'RRCKI-BUFFER', 'WriteAccess', 'Banned', 'StorageElement', 'rs_svc']

response1 = {
    'OK': True,
    'Value': [el101],
    'Columns': columns}

response2 = {
    'OK': True,
    'Value': [el101, el102],
    'Columns': columns}

response3 = {
    'OK': True,
    'Value': [el101, el102, el103],
    'Columns': columns}

response4 = {
    'OK': True,
    'Value': [el101, el102, el103, el104],
    'Columns': columns}

response4_mixed = {
    'OK': True,
    'Value': [el102, el103, el104, el101],
    'Columns': columns}

response5 = {
    'OK': True,
    'Value': [el101, el102, el103, el104, el105],
    'Columns': columns}

mockAM = MagicMock()


@pytest.fixture()
def sla(mocker):
  mocker.patch('DIRAC.ResourceStatusSystem.Agent.SummarizeLogsAgent.AgentModule', new=mockAM)
  theSLA = SummarizeLogsAgent()
  theSLA.log = gLogger
  theSLA.log.setLevel('DEBUG')
  theSLA.am_getOption = mockAM
  theSLA.rsClient = rsClientMock
  return theSLA


@pytest.mark.parametrize("rsClientMockSelectStatusElementReturnValue, expected, expectedValue", [
    (sError, False, None),
    (sOk, True, (None, {})),
    ({'OK': True, 'Value': [], 'Columns': []}, True, (None, {})),
    (response1, True, (101, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el101))]})),
    (response2, True, (102, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el101))]})),
    (response3, True, (103, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el101))],
                             ('RRCKI-BUFFER', 'ReadAccess'): [dict(zip(columns, el103))]})),
    (response4, True, (104, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el101))],
                             ('RRCKI-BUFFER', 'ReadAccess'): [dict(zip(columns, el103))]})),
    (response4_mixed, True, (101, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el102))],
                                   ('RRCKI-BUFFER', 'ReadAccess'): [dict(zip(columns, el103))]})),
    (response5, True, (105, {('RRCKI-BUFFER', 'WriteAccess'): [dict(zip(columns, el101)), dict(zip(columns, el105))],
                             ('RRCKI-BUFFER', 'ReadAccess'): [dict(zip(columns, el103))]})), ])
def test__summarizeLogs(rsClientMockSelectStatusElementReturnValue, expected, expectedValue, sla):
  rsClientMock.selectStatusElement.return_value = rsClientMockSelectStatusElementReturnValue
  res = sla._summarizeLogs('element')
  assert res['OK'] == expected
  assert res.get('Value') == expectedValue


@pytest.mark.parametrize("key, logs, rsClientMockSelectStatusElementReturnValue, expected", [
    ((None, None), [], sError, True),
    ((None, None), ['bof'], sError, False),
    ((None, None), [], sOk, True),
    ((None, None), [], {'OK': True, 'Value': [], 'Columns':['Status', 'TokenOwner']}, True),
    ((None, None), [], {'OK': True, 'Value': [['Active', 'rs_svc']], 'Columns':['status', 'tokenowner']}, True),
    (('RRCKI-BUFFER', 'WriteAccess'),  # this should remove everything
     [dict(zip(columns, el101))],
     {'OK': True, 'Value': [['Active', 'rs_svc']], 'Columns':['status', 'tokenowner']}, True),
    (('RRCKI-BUFFER', 'WriteAccess'),  # this should keep it
     [dict(zip(columns, el101))],
     {'OK': True, 'Value': [['Banned', 'rs_svc']], 'Columns':['status', 'tokenowner']}, True),
])
def test__registerLogs(key, logs, rsClientMockSelectStatusElementReturnValue, expected, sla):
  rsClientMock.selectStatusElement.return_value = rsClientMockSelectStatusElementReturnValue
  res = sla._registerLogs('Resource', key, logs)
  assert res['OK'] == expected
