/*
 * 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 whisk

import (
	"errors"
	"fmt"
	"github.com/apache/openwhisk-client-go/wski18n"
	"net/http"
	"strings"
)

type ApiService struct {
	client *Client
}

// wsk api create : Request, Response
type ApiCreateRequest struct {
	ApiDoc *Api `json:"apidoc,omitempty"`
}
type ApiCreateRequestOptions ApiOptions
type ApiCreateResponse RetApi

// wsk api list : Request, Response
type ApiListRequest struct {
}
type ApiListRequestOptions struct {
	ApiOptions
	Limit int  `url:"limit"`
	Skip  int  `url:"skip"`
	Docs  bool `url:"docs,omitempty"`
}
type ApiListResponse RetApiArray

// wsk api get : Request, Response
type ApiGetRequest struct {
	Api
}
type ApiGetRequestOptions ApiOptions
type ApiGetResponse RetApiArray

// wsk api delete : Request, Response
type ApiDeleteRequest struct {
	Api
}
type ApiDeleteRequestOptions ApiOptions
type ApiDeleteResponse struct{}

type Api struct {
	Namespace       string         `json:"namespace,omitempty"`
	ApiName         string         `json:"apiName,omitempty"`
	GatewayBasePath string         `json:"gatewayBasePath,omitempty"`
	GatewayRelPath  string         `json:"gatewayPath,omitempty"`
	GatewayMethod   string         `json:"gatewayMethod,omitempty"`
	Id              string         `json:"id,omitempty"`
	GatewayFullPath string         `json:"gatewayFullPath,omitempty"`
	Swagger         string         `json:"swagger,omitempty"`
	Action          *ApiAction     `json:"action,omitempty"`
	PathParameters  []ApiParameter `json:"pathParameters,omitempty"`
}

type ApiParameter struct {
	Name             string                 `json:"name"`
	In               string                 `json:"in"`
	Description      string                 `json:"description,omitempty"`
	Required         bool                   `json:"required,omitempty"`
	Type             string                 `json:"type,omitempty"`
	Format           string                 `json:"format,omitempty"`
	AllowEmptyValue  bool                   `json:"allowEmptyValue,omitempty"`
	Items            map[string]interface{} `json:"items,omitempty"`
	CollectionFormat string                 `json:"collectionFormat,omitempty"`
	Default          interface{}            `json:"default,omitempty"`
	Maximum          int                    `json:"maximum,omitempty"`
	ExclusiveMaximum bool                   `json:"exclusiveMaximum,omitempty"`
	Minimum          int                    `json:"minimum,omitempty"`
	ExclusiveMinimum bool                   `json:"exclusiveMinimum,omitempty"`
	MaxLength        int                    `json:"maxLength,omitempty"`
	MinLength        int                    `json:"minLength,omitempty"`
	Pattern          string                 `json:"pattern,omitempty"`
	MaxItems         int                    `json:"maxItems,omitempty"`
	MinItems         int                    `json:"minItems,omitempty"`
	UniqueItems      bool                   `json:"uniqueItems,omitempty"`
	MultipleOf       int                    `json:"multipleOf,omitempty"`
	Enum             interface{}            `json:"enum,omitempty"`
	Ref              string                 `json:"$ref,omitempty"`
}

type ApiAction struct {
	Name          string      `json:"name,omitempty"`
	Namespace     string      `json:"namespace,omitempty"`
	BackendMethod string      `json:"backendMethod,omitempty"`
	BackendUrl    string      `json:"backendUrl,omitempty"`
	Auth          string      `json:"authkey,omitempty"`
	SecureKey     interface{} `json:"secureKey,omitempty"`
}

type ApiOptions struct {
	ActionName   string `url:"action,omitempty"`
	ApiBasePath  string `url:"basepath,omitempty"`
	ApiRelPath   string `url:"relpath,omitempty"`
	ApiVerb      string `url:"operation,omitempty"`
	ApiName      string `url:"apiname,omitempty"`
	SpaceGuid    string `url:"spaceguid,omitempty"`
	AccessToken  string `url:"accesstoken,omitempty"`
	ResponseType string `url:"responsetype,omitempty"`
}

type ApiUserAuth struct {
	SpaceGuid   string `json:"spaceguid,omitempty"`
	AccessToken string `json:"accesstoken,omitempty"`
}

type RetApiArray struct {
	Apis []ApiItem `json:"apis,omitempty"`
}

type ApiItem struct {
	ApiId    string  `json:"id,omitempty"`
	QueryKey string  `json:"key,omitempty"`
	ApiValue *RetApi `json:"value,omitempty"`
}

type RetApi struct {
	Namespace string      `json:"namespace"`
	BaseUrl   string      `json:"gwApiUrl"`
	Activated bool        `json:"gwApiActivated"`
	TenantId  string      `json:"tenantId"`
	Swagger   *ApiSwagger `json:"apidoc,omitempty"`
}

type ApiSwagger struct {
	SwaggerName string                     `json:"swagger,omitempty"`
	BasePath    string                     `json:"basePath,omitempty"`
	Info        *ApiSwaggerInfo            `json:"info,omitempty"`
	Paths       map[string]*ApiSwaggerPath `json:"paths,omitempty"`
	SecurityDef interface{}                `json:"securityDefinitions,omitempty"`
	Security    interface{}                `json:"security,omitempty"`
	XConfig     interface{}                `json:"x-ibm-configuration,omitempty"`
	XRateLimit  interface{}                `json:"x-ibm-rate-limit,omitempty"`
}

type ApiSwaggerPath struct {
	Get        *ApiSwaggerOperation `json:"get,omitempty"`
	Put        *ApiSwaggerOperation `json:"put,omitempty"`
	Post       *ApiSwaggerOperation `json:"post,omitempty"`
	Delete     *ApiSwaggerOperation `json:"delete,omitempty"`
	Options    *ApiSwaggerOperation `json:"options,omitempty"`
	Head       *ApiSwaggerOperation `json:"head,omitempty"`
	Patch      *ApiSwaggerOperation `json:"patch,omitempty"`
	Parameters []ApiParameter       `json:"parameters,omitempty"`
}

func (asp *ApiSwaggerPath) MakeOperationMap() map[string]*ApiSwaggerOperation {
	var opMap map[string]*ApiSwaggerOperation = make(map[string]*ApiSwaggerOperation)
	if asp.Get != nil {
		opMap["get"] = asp.Get
	}
	if asp.Put != nil {
		opMap["put"] = asp.Put
	}
	if asp.Post != nil {
		opMap["post"] = asp.Post
	}
	if asp.Delete != nil {
		opMap["delete"] = asp.Delete
	}
	if asp.Options != nil {
		opMap["options"] = asp.Options
	}
	if asp.Head != nil {
		opMap["head"] = asp.Head
	}
	if asp.Patch != nil {
		opMap["patch"] = asp.Patch
	}
	return opMap
}

type ApiSwaggerInfo struct {
	Title   string `json:"title,omitempty"`
	Version string `json:"version,omitempty"`
}

type ApiSwaggerOperation struct {
	OperationId string                  `json:"operationId"`
	Parameters  []ApiParameter          `json:"parameters,omitempty"`
	Responses   interface{}             `json:"responses"`
	XOpenWhisk  *ApiSwaggerOpXOpenWhisk `json:"x-openwhisk,omitempty"`
}

type ApiSwaggerOpXOpenWhisk struct {
	ActionName string `json:"action"`
	Namespace  string `json:"namespace"`
	Package    string `json:"package"`
	ApiUrl     string `json:"url"`
}

// Used for printing individual APIs in non-truncated form
type ApiFilteredList struct {
	ActionName string
	ApiName    string
	BasePath   string
	RelPath    string
	Verb       string
	Url        string
}

// Used for printing individual APIs in truncated form
type ApiFilteredRow struct {
	ActionName string
	ApiName    string
	BasePath   string
	RelPath    string
	Verb       string
	Url        string
	FmtString  string
}

var ApiVerbs map[string]bool = map[string]bool{
	"GET":     true,
	"PUT":     true,
	"POST":    true,
	"DELETE":  true,
	"PATCH":   true,
	"HEAD":    true,
	"OPTIONS": true,
}

const (
	Overwrite      = true
	DoNotOverwrite = false
)

/////////////////
// Api Methods //
/////////////////

// Compare(sortable) compares api to sortable for the purpose of sorting.
// REQUIRED: sortable must also be of type ApiFilteredList.
// ***Method of type Sortable***
func (api ApiFilteredList) Compare(sortable Sortable) bool {
	// Sorts alphabetically by [BASE_PATH | API_NAME] -> REL_PATH -> API_VERB
	apiToCompare := sortable.(ApiFilteredList)
	var apiString string
	var compareString string

	apiString = strings.ToLower(fmt.Sprintf("%s%s%s", api.BasePath, api.RelPath,
		api.Verb))
	compareString = strings.ToLower(fmt.Sprintf("%s%s%s", apiToCompare.BasePath,
		apiToCompare.RelPath, apiToCompare.Verb))

	return apiString < compareString
}

// ToHeaderString() returns the header for a list of apis
func (api ApiFilteredList) ToHeaderString() string {
	return ""
}

// ToSummaryRowString() returns a compound string of required parameters for printing
//   from CLI command `wsk api list` or `wsk api-experimental list`.
// ***Method of type Sortable***
func (api ApiFilteredList) ToSummaryRowString() string {
	return fmt.Sprintf("%s %s %s %s %s %s",
		fmt.Sprintf("%s: %s\n", wski18n.T("Action"), api.ActionName),
		fmt.Sprintf("  %s: %s\n", wski18n.T("API Name"), api.ApiName),
		fmt.Sprintf("  %s: %s\n", wski18n.T("Base path"), api.BasePath),
		fmt.Sprintf("  %s: %s\n", wski18n.T("Path"), api.RelPath),
		fmt.Sprintf("  %s: %s\n", wski18n.T("Verb"), api.Verb),
		fmt.Sprintf("  %s: %s\n", wski18n.T("URL"), api.Url))
}

// Compare(sortable) compares api to sortable for the purpose of sorting.
// REQUIRED: sortable must also be of type ApiFilteredRow.
// ***Method of type Sortable***
func (api ApiFilteredRow) Compare(sortable Sortable) bool {
	// Sorts alphabetically by [BASE_PATH | API_NAME] -> REL_PATH -> API_VERB
	var apiString string
	var compareString string
	apiToCompare := sortable.(ApiFilteredRow)

	apiString = strings.ToLower(fmt.Sprintf("%s%s%s", api.BasePath, api.RelPath,
		api.Verb))
	compareString = strings.ToLower(fmt.Sprintf("%s%s%s", apiToCompare.BasePath,
		apiToCompare.RelPath, apiToCompare.Verb))

	return apiString < compareString
}

// ToHeaderString() returns the header for a list of apis
func (api ApiFilteredRow) ToHeaderString() string {
	return fmt.Sprintf("%s", fmt.Sprintf(api.FmtString, "Action", "Verb", "API Name", "URL"))
}

// ToSummaryRowString() returns a compound string of required parameters for printing
//   from CLI command `wsk api list -f` or `wsk api-experimental list -f`.
// ***Method of type Sortable***
func (api ApiFilteredRow) ToSummaryRowString() string {
	return fmt.Sprintf(api.FmtString, api.ActionName, api.Verb, api.ApiName, api.Url)
}

func (s *ApiService) List(apiListOptions *ApiListRequestOptions) (*ApiListResponse, *http.Response, error) {
	route := "web/whisk.system/apimgmt/getApi.http"

	routeUrl, err := addRouteOptions(route, apiListOptions)
	if err != nil {
		Debug(DbgError, "addRouteOptions(%s, %#v) error: '%s'\n", route, apiListOptions, err)
		errMsg := wski18n.T("Unable to add route options '{{.options}}'",
			map[string]interface{}{"options": apiListOptions})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_GENERAL, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}
	Debug(DbgInfo, "Api GET/list route with api options: %s\n", routeUrl)

	req, err := s.client.NewRequestUrl("GET", routeUrl, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson, AuthRequired)
	if err != nil {
		Debug(DbgError, "http.NewRequestUrl(GET, %s, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson) error: '%s'\n", routeUrl, err)
		errMsg := wski18n.T("Unable to create HTTP request for GET '{{.route}}': {{.err}}",
			map[string]interface{}{"route": routeUrl, "err": err})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}

	apiArray := new(ApiListResponse)
	resp, err := s.client.Do(req, &apiArray, ExitWithErrorOnTimeout)
	if err != nil {
		Debug(DbgError, "s.client.Do() error - HTTP req %s; error '%s'\n", req.URL.String(), err)
		return nil, resp, err
	}

	err = validateApiListResponse(apiArray)
	if err != nil {
		Debug(DbgError, "Not a valid ApiListReponse object\n")
		return nil, resp, err
	}

	return apiArray, resp, err
}

func (s *ApiService) Insert(api *ApiCreateRequest, options *ApiCreateRequestOptions, overwrite bool) (*ApiCreateResponse, *http.Response, error) {
	route := "web/whisk.system/apimgmt/createApi.http"
	Debug(DbgInfo, "Api PUT route: %s\n", route)

	routeUrl, err := addRouteOptions(route, options)
	if err != nil {
		Debug(DbgError, "addRouteOptions(%s, %#v) error: '%s'\n", route, options, err)
		errMsg := wski18n.T("Unable to add route options '{{.options}}'",
			map[string]interface{}{"options": options})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_GENERAL, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}
	Debug(DbgError, "Api create route with options: %s\n", routeUrl)

	req, err := s.client.NewRequestUrl("POST", routeUrl, api, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson, AuthRequired)
	if err != nil {
		Debug(DbgError, "http.NewRequestUrl(POST, %s, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson) error: '%s'\n", route, err)
		errMsg := wski18n.T("Unable to create HTTP request for POST '{{.route}}': {{.err}}",
			map[string]interface{}{"route": route, "err": err})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}

	retApi := new(ApiCreateResponse)
	resp, err := s.client.Do(req, &retApi, ExitWithErrorOnTimeout)
	if err != nil {
		Debug(DbgError, "s.client.Do() error - HTTP req %s; error '%s'\n", req.URL.String(), err)
		return nil, resp, err
	}

	err = validateApiSwaggerResponse(retApi.Swagger)
	if err != nil {
		Debug(DbgError, "Not a valid API creation response\n")
		return nil, resp, err
	}

	return retApi, resp, nil
}

func (s *ApiService) Get(api *ApiGetRequest, options *ApiGetRequestOptions) (*ApiGetResponse, *http.Response, error) {
	route := "web/whisk.system/apimgmt/getApi.http"
	Debug(DbgInfo, "Api GET route: %s\n", route)

	routeUrl, err := addRouteOptions(route, options)
	if err != nil {
		Debug(DbgError, "addRouteOptions(%s, %#v) error: '%s'\n", route, options, err)
		errMsg := wski18n.T("Unable to add route options '{{.options}}'",
			map[string]interface{}{"options": options})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_GENERAL, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}
	Debug(DbgError, "Api get route with options: %s\n", routeUrl)

	req, err := s.client.NewRequestUrl("GET", routeUrl, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson, AuthRequired)
	if err != nil {
		Debug(DbgError, "http.NewRequestUrl(GET, %s, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson) error: '%s'\n", route, err)
		errMsg := wski18n.T("Unable to create HTTP request for GET '{{.route}}': {{.err}}",
			map[string]interface{}{"route": route, "err": err})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, nil, whiskErr
	}

	retApi := new(ApiGetResponse)
	resp, err := s.client.Do(req, &retApi, ExitWithErrorOnTimeout)
	if err != nil {
		Debug(DbgError, "s.client.Do() error - HTTP req %s; error '%s'\n", req.URL.String(), err)
		return nil, resp, err
	}

	return retApi, resp, nil
}

func (s *ApiService) Delete(api *ApiDeleteRequest, options *ApiDeleteRequestOptions) (*http.Response, error) {
	route := "web/whisk.system/apimgmt/deleteApi.http"
	Debug(DbgInfo, "Api DELETE route: %s\n", route)

	routeUrl, err := addRouteOptions(route, options)
	if err != nil {
		Debug(DbgError, "addRouteOptions(%s, %#v) error: '%s'\n", route, options, err)
		errMsg := wski18n.T("Unable to add route options '{{.options}}'",
			map[string]interface{}{"options": options})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_GENERAL, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, whiskErr
	}
	Debug(DbgError, "Api DELETE route with options: %s\n", routeUrl)

	req, err := s.client.NewRequestUrl("DELETE", routeUrl, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson, AuthRequired)
	if err != nil {
		Debug(DbgError, "http.NewRequestUrl(DELETE, %s, nil, DoNotIncludeNamespaceInUrl, AppendOpenWhiskPathPrefix, EncodeBodyAsJson) error: '%s'\n", route, err)
		errMsg := wski18n.T("Unable to create HTTP request for DELETE '{{.route}}': {{.err}}",
			map[string]interface{}{"route": route, "err": err})
		whiskErr := MakeWskErrorFromWskError(errors.New(errMsg), err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG,
			NO_DISPLAY_USAGE)
		return nil, whiskErr
	}

	retApi := new(ApiDeleteResponse)
	resp, err := s.client.Do(req, &retApi, ExitWithErrorOnTimeout)
	if err != nil {
		Debug(DbgError, "s.client.Do() error - HTTP req %s; error '%s'\n", req.URL.String(), err)
		return resp, err
	}

	return nil, nil
}

func validateApiListResponse(apiList *ApiListResponse) error {
	for i := 0; i < len(apiList.Apis); i++ {
		if apiList.Apis[i].ApiValue == nil {
			Debug(DbgError, "validateApiResponse: No value stanza in api %v\n", apiList.Apis[i])
			errMsg := wski18n.T("Internal error. Missing value stanza in API configuration response")
			whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
			return whiskErr
		}
		err := validateApiSwaggerResponse(apiList.Apis[i].ApiValue.Swagger)
		if err != nil {
			Debug(DbgError, "validateApiListResponse: Invalid Api: %v\n", apiList.Apis[i])
			return err
		}
	}
	return nil
}

func validateApiSwaggerResponse(swagger *ApiSwagger) error {
	if swagger == nil {
		Debug(DbgError, "validateApiSwaggerResponse: No apidoc stanza in api\n")
		errMsg := wski18n.T("Internal error. Missing apidoc stanza in API configuration")
		whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
		return whiskErr
	}
	for path := range swagger.Paths {
		err := validateApiPath(swagger.Paths[path])
		if err != nil {
			Debug(DbgError, "validateApiResponse: Invalid Api Path object: %v\n", swagger.Paths[path])
			return err
		}
	}

	return nil
}

func validateApiPath(path *ApiSwaggerPath) error {
	for op, opv := range path.MakeOperationMap() {
		err := validateApiOperation(op, opv)
		if err != nil {
			Debug(DbgError, "validateApiPath: Invalid Api operation object: %v\n", opv)
			return err
		}
	}
	return nil
}

func validateApiOperation(opName string, op *ApiSwaggerOperation) error {
	if op.XOpenWhisk != nil && len(op.OperationId) == 0 {
		Debug(DbgError, "validateApiOperation: No operationId field in operation %v\n", op)
		errMsg := wski18n.T("Missing operationId field in API configuration for operation {{.op}}",
			map[string]interface{}{"op": opName})
		whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
		return whiskErr
	}

	if op.XOpenWhisk != nil && len(op.XOpenWhisk.Namespace) == 0 {
		Debug(DbgError, "validateApiOperation: no x-openwhisk.namespace stanza in operation %v\n", op)
		errMsg := wski18n.T("Missing x-openwhisk.namespace field in API configuration for operation {{.op}}",
			map[string]interface{}{"op": opName})
		whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
		return whiskErr
	}

	// Note: The op.XOpenWhisk.Package field can have a value of "", so don't enforce a value

	if op.XOpenWhisk != nil && len(op.XOpenWhisk.ActionName) == 0 {
		Debug(DbgError, "validateApiOperation: no x-openwhisk.action stanza in operation %v\n", op)
		errMsg := wski18n.T("Missing x-openwhisk.action field in API configuration for operation {{.op}}",
			map[string]interface{}{"op": opName})
		whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
		return whiskErr
	}
	if op.XOpenWhisk != nil && len(op.XOpenWhisk.ApiUrl) == 0 {
		Debug(DbgError, "validateApiOperation: no x-openwhisk.url stanza in operation %v\n", op)
		errMsg := wski18n.T("Missing x-openwhisk.url field in API configuration for operation {{.op}}",
			map[string]interface{}{"op": opName})
		whiskErr := MakeWskError(errors.New(errMsg), EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
		return whiskErr
	}
	return nil
}
