// Copyright 2015 go-swagger maintainers
//
// 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.

package analysis

import (
	"fmt"
	slashpath "path"
	"strconv"
	"strings"

	"github.com/go-openapi/jsonpointer"
	"github.com/go-openapi/spec"
	"github.com/go-openapi/swag"
)

type referenceAnalysis struct {
	schemas        map[string]spec.Ref
	responses      map[string]spec.Ref
	parameters     map[string]spec.Ref
	items          map[string]spec.Ref
	headerItems    map[string]spec.Ref
	parameterItems map[string]spec.Ref
	allRefs        map[string]spec.Ref
	pathItems      map[string]spec.Ref
}

func (r *referenceAnalysis) addRef(key string, ref spec.Ref) {
	r.allRefs["#"+key] = ref
}

func (r *referenceAnalysis) addItemsRef(key string, items *spec.Items, location string) {
	r.items["#"+key] = items.Ref
	r.addRef(key, items.Ref)
	if location == "header" {
		// NOTE: in swagger 2.0, headers and parameters (but not body param schemas) are simple schemas
		// and $ref are not supported here. However it is possible to analyze this.
		r.headerItems["#"+key] = items.Ref
	} else {
		r.parameterItems["#"+key] = items.Ref
	}
}

func (r *referenceAnalysis) addSchemaRef(key string, ref SchemaRef) {
	r.schemas["#"+key] = ref.Schema.Ref
	r.addRef(key, ref.Schema.Ref)
}

func (r *referenceAnalysis) addResponseRef(key string, resp *spec.Response) {
	r.responses["#"+key] = resp.Ref
	r.addRef(key, resp.Ref)
}

func (r *referenceAnalysis) addParamRef(key string, param *spec.Parameter) {
	r.parameters["#"+key] = param.Ref
	r.addRef(key, param.Ref)
}

func (r *referenceAnalysis) addPathItemRef(key string, pathItem *spec.PathItem) {
	r.pathItems["#"+key] = pathItem.Ref
	r.addRef(key, pathItem.Ref)
}

type patternAnalysis struct {
	parameters  map[string]string
	headers     map[string]string
	items       map[string]string
	schemas     map[string]string
	allPatterns map[string]string
}

func (p *patternAnalysis) addPattern(key, pattern string) {
	p.allPatterns["#"+key] = pattern
}

func (p *patternAnalysis) addParameterPattern(key, pattern string) {
	p.parameters["#"+key] = pattern
	p.addPattern(key, pattern)
}

func (p *patternAnalysis) addHeaderPattern(key, pattern string) {
	p.headers["#"+key] = pattern
	p.addPattern(key, pattern)
}

func (p *patternAnalysis) addItemsPattern(key, pattern string) {
	p.items["#"+key] = pattern
	p.addPattern(key, pattern)
}

func (p *patternAnalysis) addSchemaPattern(key, pattern string) {
	p.schemas["#"+key] = pattern
	p.addPattern(key, pattern)
}

// New takes a swagger spec object and returns an analyzed spec document.
// The analyzed document contains a number of indices that make it easier to
// reason about semantics of a swagger specification for use in code generation
// or validation etc.
func New(doc *spec.Swagger) *Spec {
	a := &Spec{
		spec:        doc,
		consumes:    make(map[string]struct{}, 150),
		produces:    make(map[string]struct{}, 150),
		authSchemes: make(map[string]struct{}, 150),
		operations:  make(map[string]map[string]*spec.Operation, 150),
		allSchemas:  make(map[string]SchemaRef, 150),
		allOfs:      make(map[string]SchemaRef, 150),
		references: referenceAnalysis{
			schemas:        make(map[string]spec.Ref, 150),
			pathItems:      make(map[string]spec.Ref, 150),
			responses:      make(map[string]spec.Ref, 150),
			parameters:     make(map[string]spec.Ref, 150),
			items:          make(map[string]spec.Ref, 150),
			headerItems:    make(map[string]spec.Ref, 150),
			parameterItems: make(map[string]spec.Ref, 150),
			allRefs:        make(map[string]spec.Ref, 150),
		},
		patterns: patternAnalysis{
			parameters:  make(map[string]string, 150),
			headers:     make(map[string]string, 150),
			items:       make(map[string]string, 150),
			schemas:     make(map[string]string, 150),
			allPatterns: make(map[string]string, 150),
		},
	}
	a.initialize()
	return a
}

// Spec is an analyzed specification object. It takes a swagger spec object and turns it into a registry
// with a bunch of utility methods to act on the information in the spec.
type Spec struct {
	spec        *spec.Swagger
	consumes    map[string]struct{}
	produces    map[string]struct{}
	authSchemes map[string]struct{}
	operations  map[string]map[string]*spec.Operation
	references  referenceAnalysis
	patterns    patternAnalysis
	allSchemas  map[string]SchemaRef
	allOfs      map[string]SchemaRef
}

func (s *Spec) reset() {
	s.consumes = make(map[string]struct{}, 150)
	s.produces = make(map[string]struct{}, 150)
	s.authSchemes = make(map[string]struct{}, 150)
	s.operations = make(map[string]map[string]*spec.Operation, 150)
	s.allSchemas = make(map[string]SchemaRef, 150)
	s.allOfs = make(map[string]SchemaRef, 150)
	s.references.schemas = make(map[string]spec.Ref, 150)
	s.references.pathItems = make(map[string]spec.Ref, 150)
	s.references.responses = make(map[string]spec.Ref, 150)
	s.references.parameters = make(map[string]spec.Ref, 150)
	s.references.items = make(map[string]spec.Ref, 150)
	s.references.headerItems = make(map[string]spec.Ref, 150)
	s.references.parameterItems = make(map[string]spec.Ref, 150)
	s.references.allRefs = make(map[string]spec.Ref, 150)
	s.patterns.parameters = make(map[string]string, 150)
	s.patterns.headers = make(map[string]string, 150)
	s.patterns.items = make(map[string]string, 150)
	s.patterns.schemas = make(map[string]string, 150)
	s.patterns.allPatterns = make(map[string]string, 150)
}

func (s *Spec) reload() {
	s.reset()
	s.initialize()
}

func (s *Spec) initialize() {
	for _, c := range s.spec.Consumes {
		s.consumes[c] = struct{}{}
	}
	for _, c := range s.spec.Produces {
		s.produces[c] = struct{}{}
	}
	for _, ss := range s.spec.Security {
		for k := range ss {
			s.authSchemes[k] = struct{}{}
		}
	}
	for path, pathItem := range s.AllPaths() {
		s.analyzeOperations(path, &pathItem)
	}

	for name, parameter := range s.spec.Parameters {
		refPref := slashpath.Join("/parameters", jsonpointer.Escape(name))
		if parameter.Items != nil {
			s.analyzeItems("items", parameter.Items, refPref, "parameter")
		}
		if parameter.In == "body" && parameter.Schema != nil {
			s.analyzeSchema("schema", *parameter.Schema, refPref)
		}
		if parameter.Pattern != "" {
			s.patterns.addParameterPattern(refPref, parameter.Pattern)
		}
	}

	for name, response := range s.spec.Responses {
		refPref := slashpath.Join("/responses", jsonpointer.Escape(name))
		for k, v := range response.Headers {
			hRefPref := slashpath.Join(refPref, "headers", k)
			if v.Items != nil {
				s.analyzeItems("items", v.Items, hRefPref, "header")
			}
			if v.Pattern != "" {
				s.patterns.addHeaderPattern(hRefPref, v.Pattern)
			}
		}
		if response.Schema != nil {
			s.analyzeSchema("schema", *response.Schema, refPref)
		}
	}

	for name, schema := range s.spec.Definitions {
		s.analyzeSchema(name, schema, "/definitions")
	}
	// TODO: after analyzing all things and flattening schemas etc
	// resolve all the collected references to their final representations
	// best put in a separate method because this could get expensive
}

func (s *Spec) analyzeOperations(path string, pi *spec.PathItem) {
	// TODO: resolve refs here?
	// Currently, operations declared via pathItem $ref are known only after expansion
	op := pi
	if pi.Ref.String() != "" {
		key := slashpath.Join("/paths", jsonpointer.Escape(path))
		s.references.addPathItemRef(key, pi)
	}
	s.analyzeOperation("GET", path, op.Get)
	s.analyzeOperation("PUT", path, op.Put)
	s.analyzeOperation("POST", path, op.Post)
	s.analyzeOperation("PATCH", path, op.Patch)
	s.analyzeOperation("DELETE", path, op.Delete)
	s.analyzeOperation("HEAD", path, op.Head)
	s.analyzeOperation("OPTIONS", path, op.Options)
	for i, param := range op.Parameters {
		refPref := slashpath.Join("/paths", jsonpointer.Escape(path), "parameters", strconv.Itoa(i))
		if param.Ref.String() != "" {
			s.references.addParamRef(refPref, &param)
		}
		if param.Pattern != "" {
			s.patterns.addParameterPattern(refPref, param.Pattern)
		}
		if param.Items != nil {
			s.analyzeItems("items", param.Items, refPref, "parameter")
		}
		if param.Schema != nil {
			s.analyzeSchema("schema", *param.Schema, refPref)
		}
	}
}

func (s *Spec) analyzeItems(name string, items *spec.Items, prefix, location string) {
	if items == nil {
		return
	}
	refPref := slashpath.Join(prefix, name)
	s.analyzeItems(name, items.Items, refPref, location)
	if items.Ref.String() != "" {
		s.references.addItemsRef(refPref, items, location)
	}
	if items.Pattern != "" {
		s.patterns.addItemsPattern(refPref, items.Pattern)
	}
}

func (s *Spec) analyzeOperation(method, path string, op *spec.Operation) {
	if op == nil {
		return
	}

	for _, c := range op.Consumes {
		s.consumes[c] = struct{}{}
	}
	for _, c := range op.Produces {
		s.produces[c] = struct{}{}
	}
	for _, ss := range op.Security {
		for k := range ss {
			s.authSchemes[k] = struct{}{}
		}
	}
	if _, ok := s.operations[method]; !ok {
		s.operations[method] = make(map[string]*spec.Operation)
	}
	s.operations[method][path] = op
	prefix := slashpath.Join("/paths", jsonpointer.Escape(path), strings.ToLower(method))
	for i, param := range op.Parameters {
		refPref := slashpath.Join(prefix, "parameters", strconv.Itoa(i))
		if param.Ref.String() != "" {
			s.references.addParamRef(refPref, &param)
		}
		if param.Pattern != "" {
			s.patterns.addParameterPattern(refPref, param.Pattern)
		}
		s.analyzeItems("items", param.Items, refPref, "parameter")
		if param.In == "body" && param.Schema != nil {
			s.analyzeSchema("schema", *param.Schema, refPref)
		}
	}
	if op.Responses != nil {
		if op.Responses.Default != nil {
			refPref := slashpath.Join(prefix, "responses", "default")
			if op.Responses.Default.Ref.String() != "" {
				s.references.addResponseRef(refPref, op.Responses.Default)
			}
			for k, v := range op.Responses.Default.Headers {
				hRefPref := slashpath.Join(refPref, "headers", k)
				s.analyzeItems("items", v.Items, hRefPref, "header")
				if v.Pattern != "" {
					s.patterns.addHeaderPattern(hRefPref, v.Pattern)
				}
			}
			if op.Responses.Default.Schema != nil {
				s.analyzeSchema("schema", *op.Responses.Default.Schema, refPref)
			}
		}
		for k, res := range op.Responses.StatusCodeResponses {
			refPref := slashpath.Join(prefix, "responses", strconv.Itoa(k))
			if res.Ref.String() != "" {
				s.references.addResponseRef(refPref, &res)
			}
			for k, v := range res.Headers {
				hRefPref := slashpath.Join(refPref, "headers", k)
				s.analyzeItems("items", v.Items, hRefPref, "header")
				if v.Pattern != "" {
					s.patterns.addHeaderPattern(hRefPref, v.Pattern)
				}
			}
			if res.Schema != nil {
				s.analyzeSchema("schema", *res.Schema, refPref)
			}
		}
	}
}

func (s *Spec) analyzeSchema(name string, schema spec.Schema, prefix string) {
	refURI := slashpath.Join(prefix, jsonpointer.Escape(name))
	schRef := SchemaRef{
		Name:     name,
		Schema:   &schema,
		Ref:      spec.MustCreateRef("#" + refURI),
		TopLevel: prefix == "/definitions",
	}

	s.allSchemas["#"+refURI] = schRef

	if schema.Ref.String() != "" {
		s.references.addSchemaRef(refURI, schRef)
	}
	if schema.Pattern != "" {
		s.patterns.addSchemaPattern(refURI, schema.Pattern)
	}

	for k, v := range schema.Definitions {
		s.analyzeSchema(k, v, slashpath.Join(refURI, "definitions"))
	}
	for k, v := range schema.Properties {
		s.analyzeSchema(k, v, slashpath.Join(refURI, "properties"))
	}
	for k, v := range schema.PatternProperties {
		// NOTE: swagger 2.0 does not support PatternProperties.
		// However it is possible to analyze this in a schema
		s.analyzeSchema(k, v, slashpath.Join(refURI, "patternProperties"))
	}
	for i, v := range schema.AllOf {
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "allOf"))
	}
	if len(schema.AllOf) > 0 {
		s.allOfs["#"+refURI] = schRef
	}
	for i, v := range schema.AnyOf {
		// NOTE: swagger 2.0 does not support anyOf constructs.
		// However it is possible to analyze this in a schema
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "anyOf"))
	}
	for i, v := range schema.OneOf {
		// NOTE: swagger 2.0 does not support oneOf constructs.
		// However it is possible to analyze this in a schema
		s.analyzeSchema(strconv.Itoa(i), v, slashpath.Join(refURI, "oneOf"))
	}
	if schema.Not != nil {
		// NOTE: swagger 2.0 does not support "not" constructs.
		// However it is possible to analyze this in a schema
		s.analyzeSchema("not", *schema.Not, refURI)
	}
	if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
		s.analyzeSchema("additionalProperties", *schema.AdditionalProperties.Schema, refURI)
	}
	if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
		// NOTE: swagger 2.0 does not support AdditionalItems.
		// However it is possible to analyze this in a schema
		s.analyzeSchema("additionalItems", *schema.AdditionalItems.Schema, refURI)
	}
	if schema.Items != nil {
		if schema.Items.Schema != nil {
			s.analyzeSchema("items", *schema.Items.Schema, refURI)
		}
		for i, sch := range schema.Items.Schemas {
			s.analyzeSchema(strconv.Itoa(i), sch, slashpath.Join(refURI, "items"))
		}
	}
}

// SecurityRequirement is a representation of a security requirement for an operation
type SecurityRequirement struct {
	Name   string
	Scopes []string
}

// SecurityRequirementsFor gets the security requirements for the operation
func (s *Spec) SecurityRequirementsFor(operation *spec.Operation) [][]SecurityRequirement {
	if s.spec.Security == nil && operation.Security == nil {
		return nil
	}

	schemes := s.spec.Security
	if operation.Security != nil {
		schemes = operation.Security
	}

	result := [][]SecurityRequirement{}
	for _, scheme := range schemes {
		if len(scheme) == 0 {
			// append a zero object for anonymous
			result = append(result, []SecurityRequirement{{}})
			continue
		}
		var reqs []SecurityRequirement
		for k, v := range scheme {
			if v == nil {
				v = []string{}
			}
			reqs = append(reqs, SecurityRequirement{Name: k, Scopes: v})
		}
		result = append(result, reqs)
	}
	return result
}

// SecurityDefinitionsForRequirements gets the matching security definitions for a set of requirements
func (s *Spec) SecurityDefinitionsForRequirements(requirements []SecurityRequirement) map[string]spec.SecurityScheme {
	result := make(map[string]spec.SecurityScheme)

	for _, v := range requirements {
		if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
			if definition != nil {
				result[v.Name] = *definition
			}
		}
	}
	return result
}

// SecurityDefinitionsFor gets the matching security definitions for a set of requirements
func (s *Spec) SecurityDefinitionsFor(operation *spec.Operation) map[string]spec.SecurityScheme {
	requirements := s.SecurityRequirementsFor(operation)
	if len(requirements) == 0 {
		return nil
	}

	result := make(map[string]spec.SecurityScheme)
	for _, reqs := range requirements {
		for _, v := range reqs {
			if v.Name == "" {
				// optional requirement
				continue
			}
			if _, ok := result[v.Name]; ok {
				// duplicate requirement
				continue
			}
			if definition, ok := s.spec.SecurityDefinitions[v.Name]; ok {
				if definition != nil {
					result[v.Name] = *definition
				}
			}
		}
	}
	return result
}

// ConsumesFor gets the mediatypes for the operation
func (s *Spec) ConsumesFor(operation *spec.Operation) []string {

	if len(operation.Consumes) == 0 {
		cons := make(map[string]struct{}, len(s.spec.Consumes))
		for _, k := range s.spec.Consumes {
			cons[k] = struct{}{}
		}
		return s.structMapKeys(cons)
	}

	cons := make(map[string]struct{}, len(operation.Consumes))
	for _, c := range operation.Consumes {
		cons[c] = struct{}{}
	}
	return s.structMapKeys(cons)
}

// ProducesFor gets the mediatypes for the operation
func (s *Spec) ProducesFor(operation *spec.Operation) []string {
	if len(operation.Produces) == 0 {
		prod := make(map[string]struct{}, len(s.spec.Produces))
		for _, k := range s.spec.Produces {
			prod[k] = struct{}{}
		}
		return s.structMapKeys(prod)
	}

	prod := make(map[string]struct{}, len(operation.Produces))
	for _, c := range operation.Produces {
		prod[c] = struct{}{}
	}
	return s.structMapKeys(prod)
}

func mapKeyFromParam(param *spec.Parameter) string {
	return fmt.Sprintf("%s#%s", param.In, fieldNameFromParam(param))
}

func fieldNameFromParam(param *spec.Parameter) string {
	// TODO: this should be x-go-name
	if nm, ok := param.Extensions.GetString("go-name"); ok {
		return nm
	}
	return swag.ToGoName(param.Name)
}

// ErrorOnParamFunc is a callback function to be invoked
// whenever an error is encountered while resolving references
// on parameters.
//
// This function takes as input the spec.Parameter which triggered the
// error and the error itself.
//
// If the callback function returns false, the calling function should bail.
//
// If it returns true, the calling function should continue evaluating parameters.
// A nil ErrorOnParamFunc must be evaluated as equivalent to panic().
type ErrorOnParamFunc func(spec.Parameter, error) bool

func (s *Spec) paramsAsMap(parameters []spec.Parameter, res map[string]spec.Parameter, callmeOnError ErrorOnParamFunc) {
	for _, param := range parameters {
		pr := param
		if pr.Ref.String() != "" {
			obj, _, err := pr.Ref.GetPointer().Get(s.spec)
			if err != nil {
				if callmeOnError != nil {
					if callmeOnError(param, fmt.Errorf("invalid reference: %q", pr.Ref.String())) {
						continue
					}
					break
				} else {
					panic(fmt.Sprintf("invalid reference: %q", pr.Ref.String()))
				}
			}
			if objAsParam, ok := obj.(spec.Parameter); ok {
				pr = objAsParam
			} else {
				if callmeOnError != nil {
					if callmeOnError(param, fmt.Errorf("resolved reference is not a parameter: %q", pr.Ref.String())) {
						continue
					}
					break
				} else {
					panic(fmt.Sprintf("resolved reference is not a parameter: %q", pr.Ref.String()))
				}
			}
		}
		res[mapKeyFromParam(&pr)] = pr
	}
}

// ParametersFor the specified operation id.
//
// Assumes parameters properly resolve references if any and that
// such references actually resolve to a parameter object.
// Otherwise, panics.
func (s *Spec) ParametersFor(operationID string) []spec.Parameter {
	return s.SafeParametersFor(operationID, nil)
}

// SafeParametersFor the specified operation id.
//
// Does not assume parameters properly resolve references or that
// such references actually resolve to a parameter object.
//
// Upon error, invoke a ErrorOnParamFunc callback with the erroneous
// parameters. If the callback is set to nil, panics upon errors.
func (s *Spec) SafeParametersFor(operationID string, callmeOnError ErrorOnParamFunc) []spec.Parameter {
	gatherParams := func(pi *spec.PathItem, op *spec.Operation) []spec.Parameter {
		bag := make(map[string]spec.Parameter)
		s.paramsAsMap(pi.Parameters, bag, callmeOnError)
		s.paramsAsMap(op.Parameters, bag, callmeOnError)

		var res []spec.Parameter
		for _, v := range bag {
			res = append(res, v)
		}
		return res
	}
	for _, pi := range s.spec.Paths.Paths {
		if pi.Get != nil && pi.Get.ID == operationID {
			return gatherParams(&pi, pi.Get)
		}
		if pi.Head != nil && pi.Head.ID == operationID {
			return gatherParams(&pi, pi.Head)
		}
		if pi.Options != nil && pi.Options.ID == operationID {
			return gatherParams(&pi, pi.Options)
		}
		if pi.Post != nil && pi.Post.ID == operationID {
			return gatherParams(&pi, pi.Post)
		}
		if pi.Patch != nil && pi.Patch.ID == operationID {
			return gatherParams(&pi, pi.Patch)
		}
		if pi.Put != nil && pi.Put.ID == operationID {
			return gatherParams(&pi, pi.Put)
		}
		if pi.Delete != nil && pi.Delete.ID == operationID {
			return gatherParams(&pi, pi.Delete)
		}
	}
	return nil
}

// ParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that
// apply for the method and path.
//
// Assumes parameters properly resolve references if any and that
// such references actually resolve to a parameter object.
// Otherwise, panics.
func (s *Spec) ParamsFor(method, path string) map[string]spec.Parameter {
	return s.SafeParamsFor(method, path, nil)
}

// SafeParamsFor the specified method and path. Aggregates them with the defaults etc, so it's all the params that
// apply for the method and path.
//
// Does not assume parameters properly resolve references or that
// such references actually resolve to a parameter object.
//
// Upon error, invoke a ErrorOnParamFunc callback with the erroneous
// parameters. If the callback is set to nil, panics upon errors.
func (s *Spec) SafeParamsFor(method, path string, callmeOnError ErrorOnParamFunc) map[string]spec.Parameter {
	res := make(map[string]spec.Parameter)
	if pi, ok := s.spec.Paths.Paths[path]; ok {
		s.paramsAsMap(pi.Parameters, res, callmeOnError)
		s.paramsAsMap(s.operations[strings.ToUpper(method)][path].Parameters, res, callmeOnError)
	}
	return res
}

// OperationForName gets the operation for the given id
func (s *Spec) OperationForName(operationID string) (string, string, *spec.Operation, bool) {
	for method, pathItem := range s.operations {
		for path, op := range pathItem {
			if operationID == op.ID {
				return method, path, op, true
			}
		}
	}
	return "", "", nil, false
}

// OperationFor the given method and path
func (s *Spec) OperationFor(method, path string) (*spec.Operation, bool) {
	if mp, ok := s.operations[strings.ToUpper(method)]; ok {
		op, fn := mp[path]
		return op, fn
	}
	return nil, false
}

// Operations gathers all the operations specified in the spec document
func (s *Spec) Operations() map[string]map[string]*spec.Operation {
	return s.operations
}

func (s *Spec) structMapKeys(mp map[string]struct{}) []string {
	if len(mp) == 0 {
		return nil
	}

	result := make([]string, 0, len(mp))
	for k := range mp {
		result = append(result, k)
	}
	return result
}

// AllPaths returns all the paths in the swagger spec
func (s *Spec) AllPaths() map[string]spec.PathItem {
	if s.spec == nil || s.spec.Paths == nil {
		return nil
	}
	return s.spec.Paths.Paths
}

// OperationIDs gets all the operation ids based on method an dpath
func (s *Spec) OperationIDs() []string {
	if len(s.operations) == 0 {
		return nil
	}
	result := make([]string, 0, len(s.operations))
	for method, v := range s.operations {
		for p, o := range v {
			if o.ID != "" {
				result = append(result, o.ID)
			} else {
				result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
			}
		}
	}
	return result
}

// OperationMethodPaths gets all the operation ids based on method an dpath
func (s *Spec) OperationMethodPaths() []string {
	if len(s.operations) == 0 {
		return nil
	}
	result := make([]string, 0, len(s.operations))
	for method, v := range s.operations {
		for p := range v {
			result = append(result, fmt.Sprintf("%s %s", strings.ToUpper(method), p))
		}
	}
	return result
}

// RequiredConsumes gets all the distinct consumes that are specified in the specification document
func (s *Spec) RequiredConsumes() []string {
	return s.structMapKeys(s.consumes)
}

// RequiredProduces gets all the distinct produces that are specified in the specification document
func (s *Spec) RequiredProduces() []string {
	return s.structMapKeys(s.produces)
}

// RequiredSecuritySchemes gets all the distinct security schemes that are specified in the swagger spec
func (s *Spec) RequiredSecuritySchemes() []string {
	return s.structMapKeys(s.authSchemes)
}

// SchemaRef is a reference to a schema
type SchemaRef struct {
	Name     string
	Ref      spec.Ref
	Schema   *spec.Schema
	TopLevel bool
}

// SchemasWithAllOf returns schema references to all schemas that are defined
// with an allOf key
func (s *Spec) SchemasWithAllOf() (result []SchemaRef) {
	for _, v := range s.allOfs {
		result = append(result, v)
	}
	return
}

// AllDefinitions returns schema references for all the definitions that were discovered
func (s *Spec) AllDefinitions() (result []SchemaRef) {
	for _, v := range s.allSchemas {
		result = append(result, v)
	}
	return
}

// AllDefinitionReferences returns json refs for all the discovered schemas
func (s *Spec) AllDefinitionReferences() (result []string) {
	for _, v := range s.references.schemas {
		result = append(result, v.String())
	}
	return
}

// AllParameterReferences returns json refs for all the discovered parameters
func (s *Spec) AllParameterReferences() (result []string) {
	for _, v := range s.references.parameters {
		result = append(result, v.String())
	}
	return
}

// AllResponseReferences returns json refs for all the discovered responses
func (s *Spec) AllResponseReferences() (result []string) {
	for _, v := range s.references.responses {
		result = append(result, v.String())
	}
	return
}

// AllPathItemReferences returns the references for all the items
func (s *Spec) AllPathItemReferences() (result []string) {
	for _, v := range s.references.pathItems {
		result = append(result, v.String())
	}
	return
}

// AllItemsReferences returns the references for all the items in simple schemas (parameters or headers).
//
// NOTE: since Swagger 2.0 forbids $ref in simple params, this should always yield an empty slice for a valid
// Swagger 2.0 spec.
func (s *Spec) AllItemsReferences() (result []string) {
	for _, v := range s.references.items {
		result = append(result, v.String())
	}
	return
}

// AllReferences returns all the references found in the document, with possible duplicates
func (s *Spec) AllReferences() (result []string) {
	for _, v := range s.references.allRefs {
		result = append(result, v.String())
	}
	return
}

// AllRefs returns all the unique references found in the document
func (s *Spec) AllRefs() (result []spec.Ref) {
	set := make(map[string]struct{})
	for _, v := range s.references.allRefs {
		a := v.String()
		if a == "" {
			continue
		}
		if _, ok := set[a]; !ok {
			set[a] = struct{}{}
			result = append(result, v)
		}
	}
	return
}

func cloneStringMap(source map[string]string) map[string]string {
	res := make(map[string]string, len(source))
	for k, v := range source {
		res[k] = v
	}
	return res
}

// ParameterPatterns returns all the patterns found in parameters
// the map is cloned to avoid accidental changes
func (s *Spec) ParameterPatterns() map[string]string {
	return cloneStringMap(s.patterns.parameters)
}

// HeaderPatterns returns all the patterns found in response headers
// the map is cloned to avoid accidental changes
func (s *Spec) HeaderPatterns() map[string]string {
	return cloneStringMap(s.patterns.headers)
}

// ItemsPatterns returns all the patterns found in simple array items
// the map is cloned to avoid accidental changes
func (s *Spec) ItemsPatterns() map[string]string {
	return cloneStringMap(s.patterns.items)
}

// SchemaPatterns returns all the patterns found in schemas
// the map is cloned to avoid accidental changes
func (s *Spec) SchemaPatterns() map[string]string {
	return cloneStringMap(s.patterns.schemas)
}

// AllPatterns returns all the patterns found in the spec
// the map is cloned to avoid accidental changes
func (s *Spec) AllPatterns() map[string]string {
	return cloneStringMap(s.patterns.allPatterns)
}
