/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 data_loader

import (
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"strconv"
	"strings"

	"github.com/getkin/kin-openapi/openapi3"
	"github.com/gin-gonic/gin"
	"github.com/shiningrush/droplet"
	"github.com/shiningrush/droplet/data"
	"github.com/shiningrush/droplet/wrapper"
	wgin "github.com/shiningrush/droplet/wrapper/gin"

	"github.com/apisix/manager-api/internal/core/entity"
	"github.com/apisix/manager-api/internal/core/store"
	"github.com/apisix/manager-api/internal/handler"
	"github.com/apisix/manager-api/internal/log"
	"github.com/apisix/manager-api/internal/utils"
	"github.com/apisix/manager-api/internal/utils/consts"
)

type Handler struct {
	routeStore    store.Interface
	upstreamStore store.Interface
	serviceStore  store.Interface
	consumerStore store.Interface
}

func NewHandler() (handler.RouteRegister, error) {
	return &Handler{
		routeStore:    store.GetStore(store.HubKeyRoute),
		upstreamStore: store.GetStore(store.HubKeyUpstream),
		serviceStore:  store.GetStore(store.HubKeyService),
		consumerStore: store.GetStore(store.HubKeyConsumer),
	}, nil
}

func (h *Handler) ApplyRoute(r *gin.Engine) {
	r.GET("/apisix/admin/export/routes/:ids", wgin.Wraps(h.ExportRoutes,
		wrapper.InputType(reflect.TypeOf(ExportInput{}))))
	r.GET("/apisix/admin/export/routes", wgin.Wraps(h.ExportAllRoutes))
}

type ExportInput struct {
	IDs string `auto_read:"ids,path"`
}

//ExportRoutes Export data by passing route ID, such as "R1" or multiple route parameters, such as "R1,R2"
func (h *Handler) ExportRoutes(c droplet.Context) (interface{}, error) {
	input := c.Input().(*ExportInput)

	if input.IDs == "" {
		return nil, consts.ErrParameterID
	}

	ids := strings.Split(input.IDs, ",")
	routes := []*entity.Route{}

	for _, id := range ids {
		route, err := h.routeStore.Get(c.Context(), id)
		if err != nil {
			if err == data.ErrNotFound {
				return nil, fmt.Errorf(consts.IDNotFound, "upstream", id)
			}
			return nil, err
		}
		routes = append(routes, route.(*entity.Route))
	}

	swagger, err := h.RouteToOpenAPI3(c, routes)
	if err != nil {
		return nil, err
	}
	return swagger, nil
}

type AuthType string

const (
	BasicAuth AuthType = "basic-auth"
	KeyAuth   AuthType = "key-auth"
	JWTAuth   AuthType = "jwt-auth"
)

var (
	openApi         = "3.0.0"
	title           = "RoutesExport"
	service         interface{}
	err             error
	routeMethods    []string
	_allHTTPMethods = []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch, http.MethodHead, http.MethodConnect, http.MethodTrace, http.MethodOptions}
)

//ExportAllRoutes All routes can be directly exported without passing parameters
func (h *Handler) ExportAllRoutes(c droplet.Context) (interface{}, error) {
	routelist, err := h.routeStore.List(c.Context(), store.ListInput{})

	if len(routelist.Rows) < 1 {
		return nil, consts.ErrRouteData
	}

	if err != nil {
		return nil, err
	}

	routes := []*entity.Route{}

	for _, route := range routelist.Rows {
		routes = append(routes, route.(*entity.Route))
	}

	swagger, err := h.RouteToOpenAPI3(c, routes)
	if err != nil {
		return nil, err
	}
	return swagger, nil
}

//RouteToOpenAPI3 Pass in route list parameter: []*entity.Route, convert route data to openapi3 and export processing function
func (h *Handler) RouteToOpenAPI3(c droplet.Context, routes []*entity.Route) (*openapi3.Swagger, error) {
	paths := openapi3.Paths{}
	paramsRefs := []*openapi3.ParameterRef{}
	requestBody := &openapi3.RequestBody{}
	components := &openapi3.Components{}
	secSchemas := openapi3.SecuritySchemes{}
	_pathNumber := GetPathNumber()

	for _, route := range routes {
		extensions := make(map[string]interface{})
		servicePlugins := make(map[string]interface{})
		plugins := make(map[string]interface{})
		serviceLabels := make(map[string]string)

		pathItem := &openapi3.PathItem{}
		path := openapi3.Operation{}
		path.Summary = route.Desc
		path.OperationID = route.Name

		if route.ServiceID != nil {
			serviceID := utils.InterfaceToString(route.ServiceID)
			service, err = h.serviceStore.Get(c.Context(), serviceID)
			if err != nil {
				if err == data.ErrNotFound {
					return nil, fmt.Errorf(consts.IDNotFound, "service", route.ServiceID)
				}
				return nil, err
			}

			_service := service.(*entity.Service)
			servicePlugins = _service.Plugins
			serviceLabels = _service.Labels
		}

		//Parse upstream
		_upstream, err := h.ParseRouteUpstream(c, route)

		if err != nil {
			log.Errorf("ParseRouteUpstream err: ", err)
			return nil, err
		} else if _upstream != nil {
			extensions["x-apisix-upstream"] = _upstream
		}

		if route.Host != "" {
			extensions["x-apisix-host"] = route.Host
		}

		if route.Hosts != nil {
			extensions["x-apisix-hosts"] = route.Hosts
		}

		//Parse Labels
		labels, err := ParseLabels(route, serviceLabels)
		if err != nil {
			log.Errorf("parseLabels err: ", err)
			return nil, err
		}

		if labels != nil {
			extensions["x-apisix-labels"] = labels
		}

		if route.RemoteAddr != "" {
			extensions["x-apisix-remote_addr"] = route.RemoteAddr
		}

		if route.RemoteAddrs != nil {
			extensions["x-apisix-remote_addrs"] = route.RemoteAddrs
		}

		if route.FilterFunc != "" {
			extensions["x-apisix-filter_func"] = route.FilterFunc
		}

		if route.Script != nil {
			extensions["x-apisix-script"] = route.Script
		}

		if route.ServiceProtocol != "" {
			extensions["x-apisix-service_protocol"] = route.ServiceProtocol
		}

		if route.Vars != nil {
			extensions["x-apisix-vars"] = route.Vars
		}

		// Parse Route URIs
		paths, paramsRefs = ParseRouteUris(route, paths, paramsRefs, pathItem, _pathNumber())

		//Parse Route Plugins
		path, secSchemas, paramsRefs, plugins, err = ParseRoutePlugins(route, paramsRefs, plugins, path, servicePlugins, secSchemas, requestBody)

		if err != nil {
			log.Errorf("parseRoutePlugins err: ", err)
			return nil, err
		}

		if len(plugins) > 0 {
			extensions["x-apisix-plugins"] = plugins
		}

		extensions["x-apisix-priority"] = route.Priority
		extensions["x-apisix-status"] = route.Status
		extensions["x-apisix-enable_websocket"] = route.EnableWebsocket
		path.Extensions = extensions
		path.Parameters = paramsRefs
		path.RequestBody = &openapi3.RequestBodyRef{Value: requestBody}
		path.Responses = openapi3.NewResponses()

		if route.Methods != nil && len(route.Methods) > 0 {
			routeMethods = route.Methods
		} else {
			routeMethods = _allHTTPMethods
		}

		for i := range routeMethods {
			switch strings.ToUpper(routeMethods[i]) {
			case http.MethodGet:
				pathItem.Get = ParsePathItem(path, http.MethodGet)
			case http.MethodPost:
				pathItem.Post = ParsePathItem(path, http.MethodPost)
			case http.MethodPut:
				pathItem.Put = ParsePathItem(path, http.MethodPut)
			case http.MethodDelete:
				pathItem.Delete = ParsePathItem(path, http.MethodDelete)
			case http.MethodPatch:
				pathItem.Patch = ParsePathItem(path, http.MethodPatch)
			case http.MethodHead:
				pathItem.Head = ParsePathItem(path, http.MethodHead)
			case http.MethodConnect:
				pathItem.Connect = ParsePathItem(path, http.MethodConnect)
			case http.MethodTrace:
				pathItem.Trace = ParsePathItem(path, http.MethodTrace)
			case http.MethodOptions:
				pathItem.Options = ParsePathItem(path, http.MethodOptions)
			}
		}
	}

	components.SecuritySchemes = secSchemas
	swagger := openapi3.Swagger{
		OpenAPI:    openApi,
		Info:       &openapi3.Info{Title: title, Version: openApi},
		Paths:      paths,
		Components: *components,
	}
	return &swagger, nil
}

//ParseLabels When service and route have labels at the same time, use route's label.
//When route has no label, service sometimes uses service's label. This function is used to process this logic
func ParseLabels(route *entity.Route, serviceLabels map[string]string) (map[string]string, error) {
	if route.Labels != nil {
		return route.Labels, nil
	} else if route.ServiceID != nil {
		return serviceLabels, nil
	}
	return nil, nil
}

//ParsePathItem Convert data in route to openapi3
func ParsePathItem(path openapi3.Operation, routeMethod string) *openapi3.Operation {
	_path := &openapi3.Operation{
		ExtensionProps: path.ExtensionProps,
		Tags:           path.Tags,
		Summary:        path.Summary,
		Description:    path.Description,
		OperationID:    path.OperationID + routeMethod,
		Parameters:     path.Parameters,
		RequestBody:    path.RequestBody,
		Responses:      path.Responses,
		Callbacks:      path.Callbacks,
		Deprecated:     path.Deprecated,
		Security:       path.Security,
		Servers:        path.Servers,
		ExternalDocs:   path.ExternalDocs,
	}
	return _path
}

// ParseRoutePlugins Merge service with plugin in route
func ParseRoutePlugins(route *entity.Route, paramsRefs []*openapi3.ParameterRef, plugins map[string]interface{}, path openapi3.Operation, servicePlugins map[string]interface{}, secSchemas openapi3.SecuritySchemes, requestBody *openapi3.RequestBody) (openapi3.Operation, openapi3.SecuritySchemes, []*openapi3.ParameterRef, map[string]interface{}, error) {
	if route.Plugins != nil {
		param := &openapi3.Parameter{}
		secReq := &openapi3.SecurityRequirements{}

		// analysis plugins
		for key, value := range route.Plugins {
			// analysis request-validation plugin
			if key == "request-validation" {
				if valueMap, ok := value.(map[string]interface{}); ok {
					if hsVal, ok := valueMap["header_schema"]; ok {
						param.In = "header"
						requestValidation := &entity.RequestValidation{}
						reqBytes, _ := json.Marshal(&hsVal)
						err := json.Unmarshal(reqBytes, requestValidation)
						if err != nil {
							log.Errorf("json marshal failed: %s", err)
						}
						for key1, value1 := range requestValidation.Properties.(map[string]interface{}) {
							for _, arr := range requestValidation.Required {
								if arr == key1 {
									param.Required = true
								}
							}
							param.Name = key1
							typeStr := value1.(map[string]interface{})
							schema := &openapi3.Schema{Type: typeStr["type"].(string)}
							param.Schema = &openapi3.SchemaRef{Value: schema}
							paramsRefs = append(paramsRefs, &openapi3.ParameterRef{Value: param})
						}
					}

					if bsVal, ok := valueMap["body_schema"]; ok {
						m := map[string]*openapi3.MediaType{}
						reqBytes, _ := json.Marshal(&bsVal)
						schema := &openapi3.Schema{}
						err := json.Unmarshal(reqBytes, schema)
						if err != nil {
							log.Errorf("json marshal failed: %s", err)
						}
						// In the swagger format conversion, there are many cases of content type data format
						// Such as (application/json, application/xml, text/xml) and more.
						// There are many matching methods, such as equal, inclusive and so on.
						// Therefore, the current processing method is to use "*/*" to match all
						m["*/*"] = &openapi3.MediaType{Schema: &openapi3.SchemaRef{Value: schema}}
						requestBody.Content = m
					}
				}
				continue
			}
			// analysis security plugins
			securityEnv := &openapi3.SecurityRequirement{}
			switch key {
			case string(KeyAuth):
				secSchemas["api_key"] = &openapi3.SecuritySchemeRef{Value: openapi3.NewCSRFSecurityScheme()}
				securityEnv.Authenticate("api_key", " ")
				secReq.With(*securityEnv)
				continue
			case string(BasicAuth):
				secSchemas["basicAuth"] = &openapi3.SecuritySchemeRef{Value: &openapi3.SecurityScheme{
					Type: "basicAuth",
					Name: "basicAuth",
					In:   "header",
				}}
				securityEnv.Authenticate("basicAuth", " ")
				secReq.With(*securityEnv)
				continue
			case string(JWTAuth):
				secSchemas["bearerAuth"] = &openapi3.SecuritySchemeRef{Value: openapi3.NewJWTSecurityScheme()}
				securityEnv.Authenticate("bearerAuth", " ")
				secReq.With(*securityEnv)
				continue
			}
			plugins[key] = value
		}
		path.Security = secReq

		if route.ServiceID != nil && servicePlugins != nil {
			_servicePlugins, err := json.Marshal(servicePlugins)
			if err != nil {
				log.Errorf("MapToJson err: ", err)
				return path, nil, nil, nil, err
			}
			_plugins, err := json.Marshal(plugins)
			if err != nil {
				log.Errorf("MapToJson err: ", err)
				return path, nil, nil, nil, err
			}
			bytePlugins, err := utils.MergeJson(_servicePlugins, _plugins)
			if err != nil {
				log.Errorf("Plugins MergeJson err: ", err)
				return path, nil, nil, nil, err
			}
			err = json.Unmarshal([]byte(bytePlugins), &plugins)
			if err != nil {
				log.Errorf("JsonToMapDemo err: ", err)
				return path, nil, nil, nil, err
			}
		}
	} else if route.Plugins == nil && route.ServiceID != nil {
		plugins = servicePlugins
	}
	return path, secSchemas, paramsRefs, plugins, nil
}

// ParseRouteUris The URI and URIs of route are converted to paths URI in openapi3
func ParseRouteUris(route *entity.Route, paths openapi3.Paths, paramsRefs []*openapi3.ParameterRef, pathItem *openapi3.PathItem, _pathNumber int) (openapi3.Paths, []*openapi3.ParameterRef) {
	routeURIs := []string{}
	if route.URI != "" {
		routeURIs = append(routeURIs, route.URI)
	}

	if route.Uris != nil {
		routeURIs = route.Uris
	}

	for _, uri := range routeURIs {
		if strings.Contains(uri, "*") {
			if _, ok := paths[strings.Split(uri, "*")[0]+"{params}"]; !ok {
				paths[strings.Split(uri, "*")[0]+"{params}"] = pathItem
			} else {
				paths[strings.Split(uri, "*")[0]+"{params}"+"-APISIX-REPEAT-URI-"+strconv.Itoa(_pathNumber)] = pathItem
			}
			// add params introduce
			paramsRefs = append(paramsRefs, &openapi3.ParameterRef{
				Value: &openapi3.Parameter{
					In:          "path",
					Name:        "params",
					Required:    true,
					Description: "params in path",
					Schema:      &openapi3.SchemaRef{Value: &openapi3.Schema{Type: "string"}}}})
		} else {
			if _, ok := paths[uri]; !ok {
				paths[uri] = pathItem
			} else {
				paths[uri+"-APISIX-REPEAT-URI-"+strconv.Itoa(_pathNumber)] = pathItem
			}
		}
	}
	return paths, paramsRefs
}

// ParseRouteUpstream Processing the upstream in service and route
func (h *Handler) ParseRouteUpstream(c droplet.Context, route *entity.Route) (interface{}, error) {
	// The upstream data of route has the highest priority.
	// If there is one, it will be used directly.
	// If there is no route, the upstream data of service will be used.
	// If there is no route, the upstream data of service will not be used normally.
	if route.Upstream != nil {
		return route.Upstream, nil
	} else if route.UpstreamID != nil && route.Upstream == nil {
		upstreamID := utils.InterfaceToString(route.UpstreamID)
		upstream, err := h.upstreamStore.Get(c.Context(), upstreamID)
		if err != nil {
			if err == data.ErrNotFound {
				return nil, fmt.Errorf(consts.IDNotFound, "upstream", route.UpstreamID)
			}
			return nil, err
		}
		return upstream, nil
	} else if route.UpstreamID == nil && route.Upstream == nil && route.ServiceID != nil {
		_service := service.(*entity.Service)
		if _service.Upstream != nil {
			return _service.Upstream, nil
		} else if _service.Upstream == nil && _service.UpstreamID != nil {
			upstreamID := utils.InterfaceToString(_service.UpstreamID)
			upstream, err := h.upstreamStore.Get(c.Context(), upstreamID)
			if err != nil {
				if err == data.ErrNotFound {
					return nil, fmt.Errorf(consts.IDNotFound, "upstream", _service.UpstreamID)
				}
				return nil, err
			}
			return upstream, nil
		}
	}
	return nil, nil
}

func GetPathNumber() func() int {
	i := 0
	return func() int {
		i++
		return i
	}
}
