# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the Shuup Commerce Inc -
# SELF HOSTED SOFTWARE LICENSE AGREEMENT executed by Shuup Commerce Inc, DBA as SHUUP®
# and the Licensee.
from django.utils.encoding import smart_text
from rest_framework import permissions, serializers
from rest_framework.compat import coreapi
from rest_framework.response import Response
from rest_framework.schemas import SchemaGenerator
from rest_framework.schemas.coreapi import AutoSchema, field_to_schema
from rest_framework.utils.formatting import dedent
from rest_framework.views import APIView
from rest_framework_swagger import renderers
from shuup.admin.utils.permissions import has_permission


class ShuupAPISchema(AutoSchema):
    def _get_method_docstring(self, view, method):
        method_name = getattr(view, "action", method.lower())
        method_docstring = getattr(view, method_name, None).__doc__
        if method_docstring:
            # An explicit docstring on the method or action.
            return dedent(smart_text(method_docstring))

    def get_description(self, path, method):
        """
        Based on original SchemaGenerator.
        This method take the class docstring directly,
        and put break lines in sections correctly.
        """
        view = self.view
        method_docstring = self._get_method_docstring(view, method)
        if method_docstring:
            return method_docstring

        return super(ShuupAPISchema, self).get_description(path, method)

    def get_serializer_fields(self, path, method):
        """
        Based on original SchemaGenerator, but this looks for
        schema_serializer_class attribute on view.
        The attribute will be available when decorated with `shuup.api.decorators.schema_serializer_class`.
        """
        view = self.view

        if method not in ("PUT", "PATCH", "POST"):
            return []

        serializer = None
        if hasattr(view, "action"):
            serialier_class = getattr(getattr(view, view.action), "schema_serializer_class", None)
            if serialier_class:
                serializer = serialier_class()
                fields = []
                for field in serializer.fields.values():
                    if field.read_only or isinstance(field, serializers.HiddenField):
                        continue

                    required = field.required and method != "PATCH"
                    field = coreapi.Field(
                        name=field.field_name, location="form", required=required, schema=field_to_schema(field)
                    )
                    fields.append(field)

                return fields

        return super(ShuupAPISchema, self).get_serializer_fields(path, method)


class JSONOpenAPIRenderer(renderers.OpenAPIRenderer):
    media_type = "application/json"


class DocsPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        return has_permission(request.user, "api.docs")


class SwaggerSchemaView(APIView):
    renderer_classes = [renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer, JSONOpenAPIRenderer]
    permission_classes = [DocsPermission]

    def get(self, request):
        generator = SchemaGenerator(title="Shuup API")
        schema = generator.get_schema(request=request)
        return Response(schema)

# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved.
#
# This source code is licensed under the Shuup Commerce Inc -
# SELF HOSTED SOFTWARE LICENSE AGREEMENT executed by Shuup Commerce Inc, DBA as SHUUP®
# and the Licensee.
from django.utils.encoding import smart_text
from rest_framework import permissions, serializers
from rest_framework.compat import coreapi
from rest_framework.response import Response
from rest_framework.schemas import SchemaGenerator
from rest_framework.schemas.coreapi import AutoSchema, field_to_schema
from rest_framework.utils.formatting import dedent
from rest_framework.views import APIView
from rest_framework_swagger import renderers
from shuup.admin.utils.permissions import has_permission


class ShuupAPISchema(AutoSchema):
    def _get_method_docstring(self, view, method):
        method_name = getattr(view, "action", method.lower())
        method_docstring = getattr(view, method_name, None).__doc__
        if method_docstring:
            # An explicit docstring on the method or action.
            return dedent(smart_text(method_docstring))

    def get_description(self, path, method):
        """
        Based on original SchemaGenerator.
        This method take the class docstring directly,
        and put break lines in sections correctly.
        """
        view = self.view
        method_docstring = self._get_method_docstring(view, method)
        if method_docstring:
            return method_docstring

        return super(ShuupAPISchema, self).get_description(path, method)

    def get_serializer_fields(self, path, method):
        """
        Based on original SchemaGenerator, but this looks for
        schema_serializer_class attribute on view.
        The attribute will be available when decorated with `shuup.api.decorators.schema_serializer_class`.
        """
        view = self.view

        if method not in ("PUT", "PATCH", "POST"):
            return []

        serializer = None
        if hasattr(view, "action"):
            serialier_class = getattr(getattr(view, view.action), "schema_serializer_class", None)
            if serialier_class:
                serializer = serialier_class()
                fields = []
                for field in serializer.fields.values():
                    if field.read_only or isinstance(field, serializers.HiddenField):
                        continue

                    required = field.required and method != "PATCH"
                    field = coreapi.Field(
                        name=field.field_name, location="form", required=required, schema=field_to_schema(field)
                    )
                    fields.append(field)

                return fields

        return super(ShuupAPISchema, self).get_serializer_fields(path, method)


class JSONOpenAPIRenderer(renderers.OpenAPIRenderer):
    media_type = "application/json"


class DocsPermission(permissions.BasePermission):
    def has_permission(self, request, view):
        return has_permission(request.user, "api.docs")


class SwaggerSchemaView(APIView):
    renderer_classes = [renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer, JSONOpenAPIRenderer]
    permission_classes = [DocsPermission]

    def get(self, request):
        generator = SchemaGenerator(title="Shuup API")
        schema = generator.get_schema(request=request)
        return Response(schema)

# -*- coding: utf-8 -*- # This file is part of Shuup. # # Copyright (c) 2012-2021, Shuup Commerce Inc. All rights reserved. # # This source code is licensed under the Shuup Commerce Inc - # SELF HOSTED SOFTWARE LICENSE AGREEMENT executed by Shuup Commerce Inc, DBA as SHUUP® # and the Licensee. # An explicit docstring on the method or action. Based on original SchemaGenerator.         This method take the class docstring directly,         and put break lines in sections correctly. Based on original SchemaGenerator, but this looks for         schema_serializer_class attribute on view.         The attribute will be available when decorated with `shuup.api.decorators.schema_serializer_class`.