<commit_before>package common

import (
	"fmt"
	"strings"
	"net/url"
	//
	"github.com/golangdaddy/tarantula/web"
	"github.com/golangdaddy/tarantula/web/validation"
	"github.com/golangdaddy/tarantula/router/common/openapi"
)

/*
type HandlerSpec struct {
	Method string `json:"method"`
	Endpoint string `json:"endpoint"`
	MockEndpoint string `json:"mockEndpoint"`
	MockPayload interface{} `json:"mockPayload,omitempty"`
	PayloadSchema interface{} `json:"payloadSchema,omitempty"`
	OptionalPayloadSchema interface{} `json:"optionalPayloadSchema,omitempty"`
	ResponseSchema interface{} `json:"responseSchema,omitempty"`
	RouteParams map[string]*validation.Config `json:"routeParams,omitempty"`
	IsFile bool `json:"isFile"`
	FilePath string `json:"filePath,omitempty"`
	Description string `json:"description,omitempty"`
}
*/

func pointerFloat64(f float64) *float64 {
	if f == 0 {
		return nil
	}
	return &f
}

// Builds the handler documentation object.
func (config *Config) BuildOpenAPISpec(req web.RequestInterface) *openapi.APISpec {

	handlers := map[*Handler]*HandlerSpec{}

	// do the legacy spec operation
	config.RLock()
	spec := config.Spec
	for _, handler := range config.Handlers {
		handlers[handler] = handler.Spec(req)
	}
	config.RUnlock()

	swaggerPath := "/swagger.json"
	_, ok := spec.Paths[swaggerPath]
	if !ok {
		spec.Paths[swaggerPath] = &openapi.Path{}
	}
	spec.Paths[swaggerPath].GET = &openapi.PathMethod{
		Produces: []string{
			"application/json",
		},
		Description: "Serves the OpenAPI spec JSON",
		Responses: openapi.Responses{
			Code200: &openapi.StatusCode{
				Description: "Done OK",
				Schema: openapi.StatusSchema{
					Type: "object",
				},
			},
		},
	}

	spec.SecurityDefinitions = map[string]*openapi.SecuritySchemeObject{}

	for handler, handlerSpec := range handlers {

		// paths need to be RFC 3986 path encoded
		k := url.PathEscape(
			strings.Replace(
				fmt.Sprintf("%s-%s", handler.Node.FullPath(), handler.Method),
				"/",
				"_",
				-1,
			),
		)

		// create the object that holds the handler's definition
		pathMethod := &openapi.PathMethod{
			OperationID: k,
			Produces: []string{
				"application/json",
			},
			Parameters: []*openapi.Parameter{},
			Description: handler.Description,
			Responses: openapi.Responses{
				Code200: &openapi.StatusCode{
					Description: "Done OK",
					Schema: openapi.StatusSchema{
						Type: "object",
					},
				},
			},
		}

		// add the security spec from the node
		if handler.Node.security != nil {
			secSpec := handler.Node.security.Spec()
			pathMethod.Security = append(
				pathMethod.Security,
				secSpec,
			)
			spec.SecurityDefinitions[secSpec.Type] = secSpec
		}

		definition := &openapi.Definition{
			Type: "object",
			Properties: map[string]openapi.Parameter{},
		}

		// check the type of payload
		switch t := handlerSpec.PayloadSchema.(type) {
			case map[string]*validation.Config:

				// dont make a param object for GET routes etc
				if len(t) == 0 { continue }

				pathMethod.Parameters = append(
					pathMethod.Parameters,
					&openapi.Parameter{
//						Required: true,
						Name: "body",
						In: "body",
						Description: handler.Description,
						Schema: &openapi.Schema{
							Ref: "#/definitions/" + k,
						},
					},
				)<commit_msg>fix spec<commit_after>package common

import (
	"fmt"
	"strings"
	"net/url"
	//
	"github.com/golangdaddy/tarantula/web"
	"github.com/golangdaddy/tarantula/web/validation"
	"github.com/golangdaddy/tarantula/router/common/openapi"
)

/*
type HandlerSpec struct {
	Method string `json:"method"`
	Endpoint string `json:"endpoint"`
	MockEndpoint string `json:"mockEndpoint"`
	MockPayload interface{} `json:"mockPayload,omitempty"`
	PayloadSchema interface{} `json:"payloadSchema,omitempty"`
	OptionalPayloadSchema interface{} `json:"optionalPayloadSchema,omitempty"`
	ResponseSchema interface{} `json:"responseSchema,omitempty"`
	RouteParams map[string]*validation.Config `json:"routeParams,omitempty"`
	IsFile bool `json:"isFile"`
	FilePath string `json:"filePath,omitempty"`
	Description string `json:"description,omitempty"`
}
*/

func pointerFloat64(f float64) *float64 {
	if f == 0 {
		return nil
	}
	return &f
}

// Builds the handler documentation object.
func (config *Config) BuildOpenAPISpec(req web.RequestInterface) *openapi.APISpec {

	handlers := map[*Handler]*HandlerSpec{}

	// do the legacy spec operation
	config.RLock()
	spec := config.Spec
	for _, handler := range config.Handlers {
		handlers[handler] = handler.Spec(req)
	}
	config.RUnlock()

	swaggerPath := "/swagger.json"
	_, ok := spec.Paths[swaggerPath]
	if !ok {
		spec.Paths[swaggerPath] = &openapi.Path{}
	}
	spec.Paths[swaggerPath].GET = &openapi.PathMethod{
		Produces: []string{
			"application/json",
		},
		Description: "Serves the OpenAPI spec JSON",
		Responses: openapi.Responses{
			Code200: &openapi.StatusCode{
				Description: "Done OK",
				Schema: openapi.StatusSchema{
					Type: "object",
				},
			},
		},
	}

	spec.SecurityDefinitions = map[string]*openapi.SecuritySchemeObject{}

	for handler, handlerSpec := range handlers {

		// paths need to be RFC 3986 path encoded
		k := url.PathEscape(
			strings.Replace(
				fmt.Sprintf("%s-%s", handler.Node.FullPath(), handler.Method),
				"/",
				"_",
				-1,
			),
		)

		// create the object that holds the handler's definition
		pathMethod := &openapi.PathMethod{
			OperationID: k,
			Produces: []string{
				"application/json",
			},
			Parameters: []*openapi.Parameter{},
			Description: handler.Description,
			Responses: openapi.Responses{
				Code200: &openapi.StatusCode{
					Description: "Done OK",
					Schema: openapi.StatusSchema{
						Type: "object",
					},
				},
			},
		}

		// add the security spec from the node
		if handler.Node.security != nil {
			secSpec := handler.Node.security.Spec()
			pathMethod.Security = append(
				pathMethod.Security,
				secSpec,
			)
			//spec.SecurityDefinitions[secSpec.Type] = secSpec
		}

		definition := &openapi.Definition{
			Type: "object",
			Properties: map[string]openapi.Parameter{},
		}

		// check the type of payload
		switch t := handlerSpec.PayloadSchema.(type) {
			case map[string]*validation.Config:

				// dont make a param object for GET routes etc
				if len(t) == 0 { continue }

				pathMethod.Parameters = append(
					pathMethod.Parameters,
					&openapi.Parameter{
//						Required: true,
						Name: "body",
						In: "body",
						Description: handler.Description,
						Schema: &openapi.Schema{
							Ref: "#/definitions/" + k,
						},
					},
				)
{'fraction_non_alphanumeric': 0.13682767027274112, 'fraction_numerical': 0.005790035044948957, 'mean_word_length': 3.702005730659026, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4524740', 'n_tokens_mistral': 2489, 'n_tokens_neox': 2067, 'n_words': 461}