/*
 * 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/incubator-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
}
