import unittest

from mock import MagicMock

from DIRAC import gLogger
from DIRAC.ResourceStatusSystem.PolicySystem.PEP          import PEP
# from DIRAC.ResourceStatusSystem.PolicySystem.PDP          import PDP
# from DIRAC.ResourceStatusSystem.PolicySystem.PolicyCaller import PolicyCaller

#############################################################################

class PolicySystemTestCase(unittest.TestCase):
  """ Base class for the PDP - PEP test cases
  """
#############################################################################

  def setUp(self):
    gLogger.setLevel( 'DEBUG' )

    self.RSMock = MagicMock()
    self.RMMock = MagicMock()
    self.RMMock.selectStatusElement.return_value = {'OK':True, 'Value': 'bla'}
    self.mockPDP = MagicMock()

#############################################################################

class PEPSuccess(PolicySystemTestCase):

#############################################################################

  def test_enforce(self):

    pep = PEP( {'ResourceStatusClient':self.RSMock, 'ResourceManagementClient': self.RMMock} )
    pep.pdp = self.mockPDP
    res = pep.enforce( None )
    self.assert_( res['OK'] )

    decisionParams = {}
    res = pep.enforce( decisionParams )
    self.assert_( res['OK'] )

    decisionParams = {'element':'Site', 'name': 'Site1'}
    decParamsPDP = dict(decisionParams)
    decParamsPDP['active'] = 'active'
    self.mockPDP.takeDecision.return_value = {'OK':True,
                                              'Value':{'policyCombinedResult': {'PolicyType':['', ''],
                                                                                'PolicyAction':[( 'aa', 'bb' )],
                                                                                'Status':'S',
                                                                                'Reason':'testReason'},
                                                       'singlePolicyResults': [{'Status': 'Active',
                                                                                'PolicyName': 'SAM_CE_Policy',
                                                                                'Reason': 'SAM:ok'},
                                                                               {'Status': 'Banned',
                                                                                'PolicyName': 'DT_Policy_Scheduled',
                                                                                'Reason': 'DT:OUTAGE in 1 hours',
                                                                                'EndDate': '2010-02-16 15:00:00'}],
                                                       'decisionParams':decParamsPDP}}
    res = pep.enforce( decisionParams )
    self.assert_( res['OK'] )

    decisionParams = {'element':'Resource', 'name': 'StorageElement', 'statusType': 'ReadAccess'}
    res = pep.enforce( decisionParams )
    self.assert_( res['OK'] )

# class PDPSuccess(PolicySystemTestCase):
#
# #############################################################################
#
#
#   def test_takeDecision(self):
#
#     for granularity in ValidRes:
#       for status in ValidStatus:
#         for oldStatus in ValidStatus:
#           if status == oldStatus: continue
#           self.mock_p.evaluate.return_value = [{'Status': status, 'Reason': 'testReason', 'PolicyName': 'test_P'}]
#           pdp = PDP(self.VO, granularity, 'XX', oldStatus, None, 'XX')
#           res = pdp.takeDecision(policyIn = self.mock_p)
#           res = res['PolicyCombinedResult']
#           self.assert_(res['Action'])
#
#           res = pdp.takeDecision(policyIn = self.mock_p, argsIn = ())
#           res = res['PolicyCombinedResult']
#           self.assert_(res['Action'])
#
#           res = pdp.takeDecision(policyIn = self.mock_p, knownInfo={})
#           res = res['PolicyCombinedResult']
#           self.assert_(res['Action'])
#
#   def test__policyCombination(self):
#
#     for granularity in ValidRes:
#       for status in ValidStatus:
#         for oldStatus in ValidStatus:
#           if status == oldStatus:
#             continue
#
#           for newStatus1 in ValidStatus:
#             for newStatus2 in ValidStatus:
#               pdp = PDP(self.VO, granularity, 'XX', status, oldStatus, 'XX')
#               polRes  = {'Status':newStatus1, 'Reason':'-Reason1-'}
#               polRes2 = {'Status':newStatus2, 'Reason':'-Reason2-'}
#
#
#               # 0 policies
#               res = pdp._policyCombination([])
#               self.assertEqual(res, {})
#
#               # 1 policy
#               res = pdp._policyCombination([polRes])
#
#               if status == 'Banned':
#                 self.assertTrue(value_of_status(res['Status']) <= 1)
#
#               if status == 'Banned' and newStatus1 in ['Active','Bad','Probing']:
#                 self.assertEqual(res['Status'], 'Probing')
#               else:
#                 self.assertEqual(res['Status'], newStatus1)
#
#
#               # 2 policies
#               res = pdp._policyCombination([polRes, polRes2])
#
#               if status == 'Banned':
#                 self.assertTrue(value_of_status(res['Status']) <= 1)
#
#               if status == 'Banned' and newStatus1 in ['Active','Bad','Probing'] and newStatus2 in ['Active','Bad','Probing']:
#                 self.assertEqual(res['Status'], 'Probing')
#
#               if status != 'Banned' and value_of_status(newStatus1) < value_of_status(newStatus1):
#                 self.assertEqual(res['Status'], newStatus1)
#               if status != 'Banned' and value_of_status(newStatus2) < value_of_status(newStatus1):
#                 self.assertEqual(res['Status'], newStatus2)
#
#               # all different policies
#               def make_polres(status):
#                 return { 'Status': status, 'Reason': 'Because of ' + status }
#               all_polres = [make_polres(s) for s in ValidStatus]
#
#               res = pdp._policyCombination(all_polres)
#               self.assertEqual(res['Status'], 'Banned')
#
# #############################################################################
#
# class PDPFailure(PolicySystemTestCase):
#
# #############################################################################
#
#   def test_PolicyFail(self):
#     for granularity in ValidRes:
#       for status in ValidStatus:
#         for oldStatus in ValidStatus:
#           if status == oldStatus:
#             continue
#           pdp = PDP(self.VO, granularity, 'XX', status, oldStatus, 'XX')
#           self.failUnlessRaises(Exception, pdp.takeDecision, self.mock_pdp, self.mock_rsDB)
#           self.failUnlessRaises(Exception, pdp.takeDecision, self.mock_pdp, self.mock_rsDB, knownInfo={'DT':'AT_RISK'})
#
# #############################################################################
#
#   def test_PDPBadInputs(self):
#     for status in ValidStatus:
#       for oldStatus in ValidStatus:
#         if status == oldStatus:
#           continue
#     for granularity in ValidRes:
#       for oldStatus in ValidStatus:
#         for status in ValidStatus:
#           if status == oldStatus:
#             continue
#
# #############################################################################
#
# class PolicyCallerSuccess(PolicySystemTestCase):
#
#   def test_policyInvocation(self):
#     cc = Mock()
#
#     policies_modules = {'Site':['DT_Policy', 'GGUSTickets_Policy'],
#                         'Service': ['PilotsEfficiency_Simple_Policy', 'JobsEfficiency_Simple_Policy'],
#                         'Resource':['SAMResults_Policy', 'DT_Policy'],
#                         'StorageElementRead':['SEOccupancy_Policy', 'TransferQuality_Policy'],
#                         'StorageElementWrite':['SEOccupancy_Policy', 'TransferQuality_Policy']
#                         }
#
#     for g in ValidRes:
#       for status in ValidStatus:
#         self.mock_p.evaluate.return_value = {'Status':status,
#                                              'Reason':'testReason',
#                                              'PolicyName': 'test_P'}
#         pc = PolicyCaller(commandCallerIn = cc)
#
#         for pol_mod in policies_modules[g]:
#           res = pc.policyInvocation(self.VO, g, 'XX', status, self.mock_p,
#                                     (g, 'XX'), None, pol_mod)
#           self.assertEqual(res['Status'], status)
#
#           res = pc.policyInvocation(self.VO, g, 'XX', status, self.mock_p,
#                                     None, None, pol_mod)
#           self.assertEqual(res['Status'], status)
#
#           for extraArgs in ((g, 'XX'), [(g, 'XX'), (g, 'XX')]):
#             res = pc.policyInvocation(self.VO, g, 'XX', status, self.mock_p,
#                                       None, None, pol_mod, extraArgs)
#             self.assertEqual(res['Status'], status)
#
# #############################################################################
#
# class PolicyBaseSuccess(PolicySystemTestCase):
#
#   def test_setArgs(self):
#     for g in ValidRes:
#       for a in [(g, 'XX')]:
#         self.pb.setArgs(a)
#         self.assertEqual(self.pb.args, a)
#
#   def test_evaluate(self):
#     for g in ValidRes:
#       for a in [(g, 'XX')]:
#         self.pb.setArgs(a)
#         self.mock_command.doCommand.return_value = {'Result':'aRes'}
#         self.pb.setCommand(self.mock_command)
#         res = self.pb.evaluate()
#         self.assertEqual(res, 'aRes')
#
# #############################################################################
#
# class PolicyBaseFailure(PolicySystemTestCase):
#
#   def test_setBadArgs(self):
#
#
#     # 6 arguments should be handled with no problem: why the limitation to 5 ?! (removing this test)
#     # self.pb.setArgs(('Site', 'XX', 'Active', 'BOH', 'BOH', 'BOH'))
#     # self.mock_command.doCommand.return_value = {'Result':'aRes'}
#     # self.pb.setCommand(self.mock_command)
#     # Lists are unsupported by Command for now, useless to test.
#     # self.pb.setArgs([('Site', 'XX', 'Active', 'BOH', 'BOH', 'BOH'), ('Site', 'XX', 'Active', 'BOH', 'BOH', 'BOH')])
#
# #############################################################################
#
# # class PolicyInvokerSuccess(PolicySystemTestCase):
#
# #   def test_setPolicy(self):
# #     self.pi.setPolicy(self.mock_policy)
# #     self.assertEqual(self.pi.policy, self.mock_policy)
#
# #   def test_evaluatePolicy(self):
#
# #     self.mock_policy.evaluate.return_value = {'Result':'Satisfied', 'Status':'Banned', 'Reason':"reason"}
# #     self.pi.setPolicy(self.mock_policy)
# #     for granularity in ValidRes:
# #       res = self.pi.evaluatePolicy()
# #       self.assertEqual(res['Result'], 'Satisfied')
# #     self.mock_policy.evaluate.return_value = {'Result':'Un-Satisfied'}
# #     self.pi.setPolicy(self.mock_policy)
# #     for granularity in ValidRes:
# #       res = self.pi.evaluatePolicy()
# #       self.assertEqual(res['Result'], 'Un-Satisfied')
#
# # #############################################################################
#
# # class PolicyInvokerFailure(PolicySystemTestCase):
#
# #   def test_policyFail(self):
# #     for granularity in ValidRes:
# #       self.failUnlessRaises(Exception, self.pi.evaluatePolicy)

#############################################################################

if __name__ == '__main__':
  suite = unittest.defaultTestLoader.loadTestsFromTestCase(PolicySystemTestCase)
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PolicyBaseSuccess))
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PolicyBaseFailure))
#  suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PolicyInvokerSuccess))
#  suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PolicyInvokerFailure))
  suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PEPSuccess))
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PEPFailure))
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PDPSuccess))
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PDPFailure))
#   suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(PolicyCallerSuccess))
  testResult = unittest.TextTestRunner(verbosity=2).run(suite)

#############################################################################
