#!/usr/bin/env python

__author__ = 'Stephen P. Henrie'

from os import path
from StringIO import StringIO

from ndg.xacml.parsers.etree.factory import ReaderFactory
from ndg.xacml.core import Identifiers, XACML_1_0_PREFIX
from ndg.xacml.core.attribute import Attribute
from ndg.xacml.core.attributevalue import AttributeValue, AttributeValueClassFactory
from ndg.xacml.core.functions import functionMap
from ndg.xacml.core.context.request import Request
from ndg.xacml.core.context.subject import Subject
from ndg.xacml.core.context.resource import Resource
from ndg.xacml.core.context.action import Action
from ndg.xacml.core.context.environment import Environment
from ndg.xacml.core.context.pdp import PDP
from ndg.xacml.core.context.result import Decision

from pyon.core import (MSG_HEADER_ACTOR, MSG_HEADER_ROLES, MSG_HEADER_OP, MSG_HEADER_FORMAT, MSG_HEADER_USER_CONTEXT_ID,
                       PROCTYPE_AGENT, PROCTYPE_SERVICE)
from pyon.core.exception import NotFound
from pyon.core.governance import SUPERUSER_ROLE, ANONYMOUS_ACTOR, DECORATOR_OP_VERB
from pyon.core.governance.governance_dispatcher import GovernanceDispatcher
from pyon.core.registry import is_ion_object, message_classes, get_class_decorator_value
from pyon.util.log import log


COMMON_SERVICE_POLICY_RULES = 'common_service_policy_rules'

ROLE_ATTRIBUTE_ID = XACML_1_0_PREFIX + 'subject:subject-role-id'
SENDER_ID = XACML_1_0_PREFIX + 'subject:subject-sender-id'
USER_CONTEXT_ID = XACML_1_0_PREFIX + 'subject:user-context-id'
USER_CONTEXT_DIFFERS = XACML_1_0_PREFIX + 'subject:user-context-differs'

RECEIVER_TYPE = XACML_1_0_PREFIX + 'resource:receiver-type'
ACTION_VERB = XACML_1_0_PREFIX + 'action:action-verb'
ACTION_PARAMETERS = XACML_1_0_PREFIX + 'action:param-dict'

DICT_TYPE_URI = AttributeValue.IDENTIFIER_PREFIX + 'dict'
OBJECT_TYPE_URI = AttributeValue.IDENTIFIER_PREFIX + 'object'

# XACML DATATYPES
attributeValueFactory = AttributeValueClassFactory()
StringAttributeValue = attributeValueFactory(AttributeValue.STRING_TYPE_URI)
IntAttributeValue = attributeValueFactory(AttributeValue.INTEGER_TYPE_URI)
DoubleAttributeValue = attributeValueFactory(AttributeValue.DOUBLE_TYPE_URI)
BooleanAttributeValue = attributeValueFactory(AttributeValue.BOOLEAN_TYPE_URI)

# Policy templates



DEFAULT_POLICY_TEMPLATE = '''<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
    xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os http://docs.oasis-open.org/xacml/access_control-xacml-2.0-policy-schema-os.xsd"
    xmlns:xf="http://www.w3.org/TR/2002/WD-xquery-operators-20020816/#"
    xmlns:md="http:www.med.example.com/schemas/record.xsd"
    PolicyId="%s"
    RuleCombiningAlgId="%s">
    <PolicyDefaults>
        <XPathVersion>http://www.w3.org/TR/1999/Rec-xpath-19991116</XPathVersion>
    </PolicyDefaults>

    %s
</Policy>'''

POLICY_RULE_CA_PERMIT_OVERRIDES = "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides"
POLICY_RULE_CA_DENY_OVERRIDES = "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides"
POLICY_RULE_CA_FIRST_APPLICABLE = "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
EMPTY_POLICY_ID = "urn:oasis:names:tc:xacml:2.0:example:policyid:empty_policy_set"


class PolicyDecisionPointManager(object):

    def __init__(self, governance_controller):
        self.resource_policy_decision_point = {}
        self.service_policy_decision_point = {}

        self.empty_pdp = self.get_empty_pdp()