# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# 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 oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import encodeutils
import six
from six.moves import http_client as http
import webob.exc
from wsme.rest import json

from glance.api import policy
from glance.api.v2.model.metadef_resource_type import ResourceType
from glance.api.v2.model.metadef_resource_type import ResourceTypeAssociation
from glance.api.v2.model.metadef_resource_type import ResourceTypeAssociations
from glance.api.v2.model.metadef_resource_type import ResourceTypes
from glance.common import exception
from glance.common import wsgi
import glance.db
import glance.gateway
from glance.i18n import _
import glance.notifier
import glance.schema

LOG = logging.getLogger(__name__)


class ResourceTypeController(object):
    def __init__(self, db_api=None, policy_enforcer=None, notifier=None):
        self.db_api = db_api or glance.db.get_api()
        self.policy = policy_enforcer or policy.Enforcer()
        self.notifier = notifier or glance.notifier.Notifier()
        self.gateway = glance.gateway.Gateway(db_api=self.db_api,
                                              notifier=self.notifier,
                                              policy_enforcer=self.policy)

    def index(self, req):
        try:
            filters = {'namespace': None}
            rs_type_repo = self.gateway.get_metadef_resource_type_repo(
                req.context)
            db_resource_type_list = rs_type_repo.list(filters=filters)
            resource_type_list = [ResourceType.to_wsme_model(
                resource_type) for resource_type in db_resource_type_list]
            resource_types = ResourceTypes()
            resource_types.resource_types = resource_type_list
        except exception.Forbidden as e:
            LOG.debug("User not permitted to retrieve metadata resource types "
                      "index")
            raise webob.exc.HTTPForbidden(explanation=e.msg)
        except exception.NotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.msg)
        except Exception as e:
            LOG.error(encodeutils.exception_to_unicode(e))
            raise webob.exc.HTTPInternalServerError(e)
        return resource_types

    def show(self, req, namespace):
        try:
            filters = {'namespace': namespace}
            rs_type_repo = self.gateway.get_metadef_resource_type_repo(
                req.context)
            db_resource_type_list = rs_type_repo.list(filters=filters)
            resource_type_list = [ResourceTypeAssociation.to_wsme_model(
                resource_type) for resource_type in db_resource_type_list]
            resource_types = ResourceTypeAssociations()
            resource_types.resource_type_associations = resource_type_list
        except exception.Forbidden as e:
            LOG.debug("User not permitted to retrieve metadata resource types "
                      "within '%s' namespace", namespace)
            raise webob.exc.HTTPForbidden(explanation=e.msg)
        except exception.NotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.msg)
        except Exception as e:
            LOG.error(encodeutils.exception_to_unicode(e))
            raise webob.exc.HTTPInternalServerError(e)
        return resource_types

    def create(self, req, resource_type, namespace):
        rs_type_factory = self.gateway.get_metadef_resource_type_factory(
            req.context)
        rs_type_repo = self.gateway.get_metadef_resource_type_repo(req.context)
        try:
            new_resource_type = rs_type_factory.new_resource_type(
                namespace=namespace, **resource_type.to_dict())
            rs_type_repo.add(new_resource_type)

        except exception.Forbidden as e:
            LOG.debug("User not permitted to create metadata resource type "
                      "within '%s' namespace", namespace)
            raise webob.exc.HTTPForbidden(explanation=e.msg)
        except exception.NotFound as e:
            raise webob.exc.HTTPNotFound(explanation=e.msg)
        except exception.Duplicate as e:
            raise webob.exc.HTTPConflict(explanation=e.msg)
        except Exception as e:
            LOG.error(encodeutils.exception_to_unicode(e))
            raise webob.exc.HTTPInternalServerError()
        return ResourceTypeAssociation.to_wsme_model(new_resource_type)

    def delete(self, req, namespace, resource_type):
        rs_type_repo = self.gateway.get_metadef_resource_type_repo(req.context)
        try:
            filters = {}
            found = False
            filters['namespace'] = namespace