// 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 validate

// TODO: define this as package validate/internal
// This must be done while keeping CI intact with all tests and test coverage

import (
	"reflect"
	"strconv"
	"strings"

	"github.com/go-openapi/errors"
	"github.com/go-openapi/spec"
)

const swaggerBody = "body"
const objectType = "object"

// Helpers available at the package level
var (
	pathHelp     *pathHelper
	valueHelp    *valueHelper
	errorHelp    *errorHelper
	paramHelp    *paramHelper
	responseHelp *responseHelper
)

type errorHelper struct {
	// A collection of unexported helpers for error construction
}

func (h *errorHelper) sErr(err errors.Error) *Result {
	// Builds a Result from standard errors.Error
	return &Result{Errors: []error{err}}
}

func (h *errorHelper) addPointerError(res *Result, err error, ref string, fromPath string) *Result {
	// Provides more context on error messages
	// reported by the jsoinpointer package by altering the passed Result
	if err != nil {
		res.AddErrors(cannotResolveRefMsg(fromPath, ref, err))
	}
	return res
}

type pathHelper struct {
	// A collection of unexported helpers for path validation
}

func (h *pathHelper) stripParametersInPath(path string) string {
	// Returns a path stripped from all path parameters, with multiple or trailing slashes removed.
	//
	// Stripping is performed on a slash-separated basis, e.g '/a{/b}' remains a{/b} and not /a.
	//  - Trailing "/" make a difference, e.g. /a/ !~ /a (ex: canary/bitbucket.org/swagger.json)
	//  - presence or absence of a parameter makes a difference, e.g. /a/{log} !~ /a/ (ex: canary/kubernetes/swagger.json)

	// Regexp to extract parameters from path, with surrounding {}.
	// NOTE: important non-greedy modifier
	rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`)
	strippedSegments := []string{}

	for _, segment := range strings.Split(path, "/") {
		strippedSegments = append(strippedSegments, rexParsePathParam.ReplaceAllString(segment, "X"))
	}
	return strings.Join(strippedSegments, "/")
}

func (h *pathHelper) extractPathParams(path string) (params []string) {
	// Extracts all params from a path, with surrounding "{}"
	rexParsePathParam := mustCompileRegexp(`{[^{}]+?}`)

	for _, segment := range strings.Split(path, "/") {
		for _, v := range rexParsePathParam.FindAllStringSubmatch(segment, -1) {
			params = append(params, v...)
		}
	}
	return
}

type valueHelper struct {
	// A collection of unexported helpers for value validation
}

func (h *valueHelper) asInt64(val interface{}) int64 {
	// Number conversion function for int64, without error checking
	// (implements an implicit type upgrade).
	v := reflect.ValueOf(val)
	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int()
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return int64(v.Uint())
	case reflect.Float32, reflect.Float64:
		return int64(v.Float())
	default:
		//panic("Non numeric value in asInt64()")
		return 0
	}
}

func (h *valueHelper) asUint64(val interface{}) uint64 {
	// Number conversion function for uint64, without error checking
	// (implements an implicit type upgrade).
	v := reflect.ValueOf(val)
	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return uint64(v.Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.Uint()
	case reflect.Float32, reflect.Float64:
		return uint64(v.Float())
	default:
		//panic("Non numeric value in asUint64()")
		return 0
	}
}

// Same for unsigned floats
func (h *valueHelper) asFloat64(val interface{}) float64 {
	// Number conversion function for float64, without error checking
	// (implements an implicit type upgrade).
	v := reflect.ValueOf(val)
	switch v.Kind() {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return float64(v.Int())
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return float64(v.Uint())
	case reflect.Float32, reflect.Float64:
		return v.Float()
	default:
		//panic("Non numeric value in asFloat64()")
		return 0
	}
}

type paramHelper struct {
	// A collection of unexported helpers for parameters resolution
}

func (h *paramHelper) safeExpandedParamsFor(path, method, operationID string, res *Result, s *SpecValidator) (params []spec.Parameter) {
	operation, ok := s.analyzer.OperationFor(method, path)
	if ok {
		// expand parameters first if necessary
		resolvedParams := []spec.Parameter{}
		for _, ppr := range operation.Parameters {
			resolvedParam, red := h.resolveParam(path, method, operationID, &ppr, s)
			res.Merge(red)
			if resolvedParam != nil {
				resolvedParams = append(resolvedParams, *resolvedParam)
			}
		}
		// remove params with invalid expansion from Slice
		operation.Parameters = resolvedParams

		for _, ppr := range s.analyzer.SafeParamsFor(method, path,
			func(p spec.Parameter, err error) bool {
				// since params have already been expanded, there are few causes for error
				res.AddErrors(someParametersBrokenMsg(path, method, operationID))
				// original error from analyzer
				res.AddErrors(err)
				return true
			}) {
			params = append(params, ppr)
		}
	}
	return
}

func (h *paramHelper) resolveParam(path, method, operationID string, param *spec.Parameter, s *SpecValidator) (*spec.Parameter, *Result) {
	// Ensure parameter is expanded
	var err error
	res := new(Result)
	isRef := param.Ref.String() != ""
	if s.spec.SpecFilePath() == "" {
		err = spec.ExpandParameterWithRoot(param, s.spec.Spec(), nil)
	} else {
		err = spec.ExpandParameter(param, s.spec.SpecFilePath())

	}
	if err != nil { // Safeguard
		// NOTE: we may enter enter here when the whole parameter is an unresolved $ref
		refPath := strings.Join([]string{"\"" + path + "\"", method}, ".")
		errorHelp.addPointerError(res, err, param.Ref.String(), refPath)
		return nil, res
	}
	res.Merge(h.checkExpandedParam(param, param.Name, param.In, operationID, isRef))
	return param, res
}

func (h *paramHelper) checkExpandedParam(pr *spec.Parameter, path, in, operation string, isRef bool) *Result {
	// Secure parameter structure after $ref resolution
	res := new(Result)
	simpleZero := spec.SimpleSchema{}
	// Try to explain why... best guess
	if pr.In == swaggerBody && (pr.SimpleSchema != simpleZero && pr.SimpleSchema.Type != objectType) {
		if isRef {
			// Most likely, a $ref with a sibling is an unwanted situation: in itself this is a warning...
			// but we detect it because of the following error:
			// schema took over Parameter for an unexplained reason
			res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation))
		}
		res.AddErrors(invalidParameterDefinitionMsg(path, in, operation))
	} else if pr.In != swaggerBody && pr.Schema != nil {
		if isRef {
			res.AddWarnings(refShouldNotHaveSiblingsMsg(path, operation))
		}
		res.AddErrors(invalidParameterDefinitionAsSchemaMsg(path, in, operation))
	} else if (pr.In == swaggerBody && pr.Schema == nil) ||
		(pr.In != swaggerBody && pr.SimpleSchema == simpleZero) { // Safeguard
		// Other unexpected mishaps
		res.AddErrors(invalidParameterDefinitionMsg(path, in, operation))
	}
	return res
}

type responseHelper struct {
	// A collection of unexported helpers for response resolution
}

func (r *responseHelper) expandResponseRef(
	response *spec.Response,
	path string, s *SpecValidator) (*spec.Response, *Result) {
	// Ensure response is expanded
	var err error
	res := new(Result)
	if s.spec.SpecFilePath() == "" {
		// there is no physical document to resolve $ref in response
		err = spec.ExpandResponseWithRoot(response, s.spec.Spec(), nil)
	} else {
		err = spec.ExpandResponse(response, s.spec.SpecFilePath())
	}
	if err != nil { // Safeguard
		// NOTE: we may enter here when the whole response is an unresolved $ref.
		errorHelp.addPointerError(res, err, response.Ref.String(), path)
		return nil, res
	}
	return response, res
}

func (r *responseHelper) responseMsgVariants(
	responseType string,
	responseCode int) (responseName, responseCodeAsStr string) {
	// Path variants for messages
	if responseType == "default" {
		responseCodeAsStr = "default"
		responseName = "default response"
	} else {
		responseCodeAsStr = strconv.Itoa(responseCode)
		responseName = "response " + responseCodeAsStr
	}
	return
}
