1// Copyright 2017 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package surface_v1
16
17import (
18	"log"
19	nethttp "net/http"
20	"net/url"
21	"path"
22	"strconv"
23	"strings"
24)
25
26// The structure to transport information during the recursive calls inside model_openapiv2.go
27// and model_openapiv3.go
28type FieldInfo struct {
29	fieldKind   FieldKind
30	fieldType   string
31	fieldFormat string
32	// For parameters
33	fieldPosition Position
34	fieldName     string
35}
36
37func (m *Model) addType(t *Type) {
38	m.Types = append(m.Types, t)
39}
40
41func (m *Model) addMethod(method *Method) {
42	m.Methods = append(m.Methods, method)
43}
44
45func (m *Model) TypeWithTypeName(name string) *Type {
46	if name == "" {
47		return nil
48	}
49	for _, t := range m.Types {
50		if t.TypeName == name {
51			return t
52		}
53	}
54	return nil
55}
56
57func generateOperationName(method, path string) string {
58	filteredPath := strings.Replace(path, "/", "_", -1)
59	filteredPath = strings.Replace(filteredPath, ".", "_", -1)
60	filteredPath = strings.Replace(filteredPath, "{", "", -1)
61	filteredPath = strings.Replace(filteredPath, "}", "", -1)
62	return strings.Title(method) + filteredPath
63}
64
65func sanitizeOperationName(name string) string {
66	name = strings.Title(name)
67	name = strings.Replace(name, ".", "_", -1)
68	return name
69}
70
71func typeForRef(ref string) (typeName string) {
72	return path.Base(ref)
73}
74
75// Helper method to build a surface model Type
76func makeType(name string) *Type {
77	t := &Type{
78		Name:   name,
79		Kind:   TypeKind_STRUCT,
80		Fields: make([]*Field, 0),
81	}
82	return t
83}
84
85// Helper method to build a surface model Field
86func makeFieldAndAppendToType(info *FieldInfo, schemaType *Type, fieldName string) {
87	if info != nil {
88		f := &Field{Name: info.fieldName}
89		if fieldName != "" {
90			f.Name = fieldName
91		}
92		f.Type, f.Kind, f.Format, f.Position = info.fieldType, info.fieldKind, info.fieldFormat, info.fieldPosition
93		schemaType.Fields = append(schemaType.Fields, f)
94	}
95}
96
97// Helper method to determine the type of the value property for a map.
98func determineMapValueType(fInfo FieldInfo) (mapValueType string) {
99	if fInfo.fieldKind == FieldKind_ARRAY {
100		mapValueType = "[]"
101	}
102	if fInfo.fieldFormat != "" {
103		fInfo.fieldType = fInfo.fieldFormat
104	}
105	mapValueType += fInfo.fieldType
106	return mapValueType
107}
108
109// Converts a string status code like: "504" into the corresponding text ("Gateway_Timeout")
110func convertStatusCodeToText(c string) (statusText string) {
111	code, err := strconv.Atoi(c)
112	if err == nil {
113		statusText = nethttp.StatusText(code)
114		if statusText == "" {
115			log.Println("Status code " + c + " is not known to net.http.StatusText. This might cause unpredictable behavior.")
116			statusText = "unknownStatusCode"
117		}
118		statusText = strings.Replace(statusText, " ", "_", -1)
119	}
120	return statusText
121}
122
123// Searches all created types so far and returns the Type where 'typeName' matches.
124func findType(types []*Type, typeName string) *Type {
125	for _, t := range types {
126		if typeName == t.Name {
127			return t
128		}
129	}
130	return nil
131}
132
133// Returns true if s is a valid URL.
134func isSymbolicReference(s string) bool {
135	_, err := url.ParseRequestURI(s)
136	if err != nil {
137		return false
138	}
139	return true
140}
141
142// Replace encoded URLS with actual characters
143func validTypeForRef(XRef string) string {
144	t, _ := url.QueryUnescape(typeForRef(XRef))
145	return t
146}
147