#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from heat.common import exception
from heat.common.i18n import _
from heat.engine import constraints
from heat.engine import properties
from heat.engine import resource
from heat.engine import support

NOVA_MICROVERSIONS = (MICROVERSION_SOFT_POLICIES) = ('2.15')


class ServerGroup(resource.Resource):
    """A resource for managing a Nova server group.

    Server groups allow you to make sure instances (VM/VPS) are on the same
    hypervisor host or on a different one.
    """

    support_status = support.SupportStatus(version='2014.2')

    default_client_name = 'nova'

    entity = 'server_groups'

    PROPERTIES = (
        NAME, POLICIES
    ) = (
        'name', 'policies'
    )

    properties_schema = {
        NAME: properties.Schema(
            properties.Schema.STRING,
            _('Server Group name.')
        ),
        POLICIES: properties.Schema(
            properties.Schema.LIST,
            _('A list of string policies to apply. '
              'Defaults to anti-affinity.'),
            default=['anti-affinity'],
            constraints=[
                constraints.AllowedValues(["anti-affinity", "affinity",
                                           "soft-anti-affinity",
                                           "soft-affinity"])
            ],
            schema=properties.Schema(
                properties.Schema.STRING,
            )
        ),
    }

    def validate(self):
        super(ServerGroup, self).validate()
        policies = self.properties[self.POLICIES]
        is_supported = self.client_plugin().is_version_supported(
            MICROVERSION_SOFT_POLICIES)
        if (('soft-affinity' in policies or
             'soft-anti-affinity' in policies) and not is_supported):
            msg = _('Required microversion for soft policies not supported.')
            raise exception.StackValidationFailed(message=msg)

    def handle_create(self):
        name = self.physical_resource_name()
        policies = self.properties[self.POLICIES]
        client = self.client(version=MICROVERSION_SOFT_POLICIES)
        server_group = client.server_groups.create(name=name,
                                                   policies=policies)
        self.resource_id_set(server_group.id)

    def physical_resource_name(self):
        name = self.properties[self.NAME]
        if name:
            return name
        return super(ServerGroup, self).physical_resource_name()


def resource_mapping():
    return {'OS::Nova::ServerGroup': ServerGroup}

@@ -820,18 +820,117 @@
 CIES
-) = ('2.15
+, MICROVERSION_RULE) = ('2.15',%0A                                                                        '2.64
 ')%0A%0A
@@ -1316,16 +1316,22 @@
 POLICIES
+, RULE
 %0A    ) =
@@ -1359,16 +1359,24 @@
 olicies'
+, 'rule'
 %0A    )%0A%0A
@@ -2061,16 +2061,263 @@
        )
+,%0A        ),%0A        RULE: properties.Schema(%0A            properties.Schema.MAP,%0A            _('A rule for the policy. Currently, only the '%0A              '%22max_server_per_host%22 rule is supported for the '%0A              '%22anti-affinity%22 policy.'),
 %0A       
@@ -2815,193 +2815,857 @@
     
-def handle_create(self):%0A        name = self.physical_resource_name()%0A        policies = self.properties%5Bself.POLICIES%5D%0A        client = self.client(version=MICROVERSION_SOFT_POLICIES)%0A
+    if self.properties%5Bself.RULE%5D:%0A            is_supported = self.client_plugin().is_version_supported(%0A                MICROVERSION_RULE)%0A            if not is_supported:%0A                msg = _('Required microversion for rule not supported.')%0A                raise exception.StackValidationFailed(message=msg)%0A%0A    def handle_create(self):%0A        name = self.physical_resource_name()%0A        policies = self.properties%5Bself.POLICIES%5D%0A        if self.properties%5Bself.RULE%5D and 'soft-affinity' in policies:%0A            rule = self.properties%5Bself.RULE%5D%0A            client = self.client()%0A            server_group = client.server_groups.create(name=name,%0A                                                       policies=policies,%0A                                                       rule=rule)%0A        else:%0A            client = self.client()%0A    
     
@@ -3714,32 +3714,36 @@
 eate(name=name,%0A
+    
                 

Add "rule" property for anti-affinity