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

import (
	"fmt"
	"github.com/apache/openwhisk-wskdeploy/wski18n"
	"github.com/apache/openwhisk-wskdeploy/wskprint"
	"io/ioutil"
	"net/http"
	"path/filepath"
	"runtime"
	"strings"
)

const (
	// Error message compositional strings
	STR_UNKNOWN_VALUE         = "Unknown value"
	STR_COMMAND               = "Command"
	STR_ERROR_CODE            = "Error code"
	STR_FILE                  = "File"
	STR_PARAMETER             = "Parameter"
	STR_TYPE                  = "Type"
	STR_EXPECTED              = "Expected"
	STR_ACTUAL                = "Actual"
	STR_NEWLINE               = "\n"
	STR_ACTION                = "Action"
	STR_RUNTIME               = "Runtime"
	STR_SUPPORTED_RUNTIMES    = "Supported Runtimes"
	STR_HTTP_STATUS           = "HTTP Response Status"
	STR_HTTP_BODY             = "HTTP Response Body"
	STR_SUPPORTED_WEB_EXPORTS = "Supported Web Exports"
	STR_WEB_EXPORT            = "web-export"
	STR_API                   = "API"
	STR_API_METHOD            = "API gateway method"
	STR_API_SUPPORTED_METHODS = "API gateway supported methods"

	// Formatting
	STR_INDENT_1 = "==>"

	// Error Types
	ERROR_COMMAND_FAILED                  = "ERROR_COMMAND_FAILED"
	ERROR_WHISK_CLIENT_ERROR              = "ERROR_WHISK_CLIENT_ERROR"
	ERROR_WHISK_CLIENT_INVALID_CONFIG     = "ERROR_WHISK_CLIENT_INVALID_CONFIG"
	ERROR_FILE_READ_ERROR                 = "ERROR_FILE_READ_ERROR"
	ERROR_MANIFEST_FILE_NOT_FOUND         = "ERROR_MANIFEST_FILE_NOT_FOUND"
	ERROR_YAML_FILE_FORMAT_ERROR          = "ERROR_YAML_FILE_FORMAT_ERROR"
	ERROR_YAML_PARSER_ERROR               = "ERROR_YAML_PARSER_ERROR"
	ERROR_YAML_PARAMETER_TYPE_MISMATCH    = "ERROR_YAML_PARAMETER_TYPE_MISMATCH"
	ERROR_YAML_INVALID_PARAMETER_TYPE     = "ERROR_YAML_INVALID_PARAMETER_TYPE"
	ERROR_YAML_INVALID_RUNTIME            = "ERROR_YAML_INVALID_RUNTIME"
	ERROR_YAML_INVALID_WEB_EXPORT         = "ERROR_YAML_INVALID_WEB_EXPORT"
	ERROR_YAML_INVALID_API                = "ERROR_YAML_INVALID_API"
	ERROR_YAML_INVALID_API_GATEWAY_METHOD = "ERROR_YAML_INVALID_API_GATEWAY_METHOD"
	ERROR_RUNTIME_PARSER_FAILURE          = "ERROR_RUNTIME_PARSER_FAILURE"
	ERROR_ACTION_ANNOTATION               = "ERROR_ACTION_ANNOTATION"
)

/*
 * BaseError
 */
type WskDeployBaseErr struct {
	ErrorType     string
	FileName      string
	LineNum       int
	Message       string
	MessageFormat string
}

func NewWskDeployBaseError(typ string, fn string, ln int, msg string) *WskDeployBaseErr {
	var err = &WskDeployBaseErr{
		ErrorType: typ,
		FileName:  fn,
		LineNum:   ln,
	}
	err.SetMessage(msg)
	return err
}

func (e *WskDeployBaseErr) Error() string {
	return fmt.Sprintf("%s [%d]: [%s]: %s\n", e.FileName, e.LineNum, e.ErrorType, e.Message)
}

func (e *WskDeployBaseErr) SetFileName(fileName string) {
	e.FileName = filepath.Base(fileName)
}

func (e *WskDeployBaseErr) SetLineNum(lineNum int) {
	e.LineNum = lineNum
}

func (e *WskDeployBaseErr) SetErrorType(errorType string) {
	e.ErrorType = errorType
}

func (e *WskDeployBaseErr) SetMessageFormat(fmt string) {
	e.MessageFormat = fmt
}

func (e *WskDeployBaseErr) GetMessage() string {
	return e.Message
}

func (e *WskDeployBaseErr) GetMessageFormat() string {
	return e.MessageFormat
}

func (e *WskDeployBaseErr) SetMessage(message interface{}) {

	if message != nil {
		switch message.(type) {
		case string:
			e.Message = message.(string)
		case error:
			err := message.(error)
			e.appendErrorDetails(err)
		}
	}
}

func (e *WskDeployBaseErr) AppendDetail(detail string) {
	e.appendDetail(detail)
}

func (e *WskDeployBaseErr) appendDetail(detail string) {
	fmt := fmt.Sprintf("\n%s %s", STR_INDENT_1, detail)
	e.Message = e.Message + fmt
}

func (e *WskDeployBaseErr) appendErrorDetails(err error) {
	if err != nil {
		errorMsg := err.Error()
		var detailMsg string
		msgs := strings.Split(errorMsg, STR_NEWLINE)
		for i := 0; i < len(msgs); i++ {
			detailMsg = msgs[i]
			e.appendDetail(strings.TrimSpace(detailMsg))
		}
	}
}

// func Caller(skip int) (pc uintptr, file string, line int, ok bool)
func (e *WskDeployBaseErr) SetCallerByStackFrameSkip(skip int) {
	_, fname, lineNum, _ := runtime.Caller(skip)
	e.SetFileName(fname)
	e.SetLineNum(lineNum)
}

/*
 * CommandError
 */
type CommandError struct {
	WskDeployBaseErr
	Command string
}

func NewCommandError(cmd string, errorMessage string) *CommandError {
	var err = &CommandError{
		Command: cmd,
	}
	err.SetErrorType(ERROR_COMMAND_FAILED)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessageFormat("%s: [%s]: %s")
	str := fmt.Sprintf(err.MessageFormat, STR_COMMAND, cmd, errorMessage)
	err.SetMessage(str)
	return err
}

/*
 * WhiskClientError
 */
type WhiskClientError struct {
	WskDeployBaseErr
	ErrorCode int
}

func NewWhiskClientError(errorMessage string, code int, response *http.Response) *WhiskClientError {
	var err = &WhiskClientError{
		ErrorCode: code,
	}
	err.SetErrorType(ERROR_WHISK_CLIENT_ERROR)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessageFormat("%s: %d: %s")
	var str = fmt.Sprintf(err.MessageFormat, STR_ERROR_CODE, code, errorMessage)
	if response != nil {
		responseData, _ := ioutil.ReadAll(response.Body)
		err.SetMessageFormat("%s: %d: %s: %s: %s %s: %s")
		// do not add body in case of a success
		// when response.Status is 200, response.Body contains the entire action source code
		// we should not expose the action source when the HTTP request was successful
		if strings.Contains(response.Status, "200 OK") {
			str = fmt.Sprintf(err.MessageFormat, STR_ERROR_CODE, code, errorMessage, STR_HTTP_STATUS, response.Status, "", "")
		} else {
			str = fmt.Sprintf(err.MessageFormat, STR_ERROR_CODE, code, errorMessage, STR_HTTP_STATUS, response.Status, STR_HTTP_BODY, string(responseData))
		}
	}
	err.SetMessage(str)
	return err
}

/*
 * WhiskClientInvalidConfigError
 */
type WhiskClientInvalidConfigError struct {
	WskDeployBaseErr
}

func NewWhiskClientInvalidConfigError(errorMessage string) *WhiskClientInvalidConfigError {
	var err = &WhiskClientInvalidConfigError{}
	err.SetErrorType(ERROR_WHISK_CLIENT_INVALID_CONFIG)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessage(errorMessage)
	return err
}

/*
 * FileError
 */
type FileError struct {
	WskDeployBaseErr
	ErrorFileName string
	ErrorFilePath string
}

func (e *FileError) SetErrorFilePath(fpath string) {
	e.ErrorFilePath = fpath
	e.ErrorFileName = filepath.Base(fpath)
}

func (e *FileError) SetErrorFileName(fname string) {
	e.ErrorFilePath = fname
}

func (e *FileError) Error() string {
	return fmt.Sprintf("%s [%d]: [%s]: "+STR_FILE+": [%s]: %s\n",
		e.FileName,
		e.LineNum,
		e.ErrorType,
		e.ErrorFileName,
		e.Message)
}

/*
 * FileReadError
 */

type FileReadError struct {
	FileError
}

func NewFileReadError(fpath string, errMessage interface{}) *FileReadError {
	var err = &FileReadError{}
	err.SetErrorType(ERROR_FILE_READ_ERROR)
	err.SetCallerByStackFrameSkip(2)
	err.SetErrorFilePath(fpath)
	err.SetMessage(errMessage)
	return err
}

/*
 * ManifestFileNotFoundError
 */
type ErrorManifestFileNotFound struct {
	FileError
}

func NewErrorManifestFileNotFound(fpath string, errMessage interface{}) *ErrorManifestFileNotFound {
	var err = &ErrorManifestFileNotFound{}
	err.SetErrorType(ERROR_MANIFEST_FILE_NOT_FOUND)
	err.SetCallerByStackFrameSkip(2)
	err.SetErrorFilePath(fpath)
	err.SetMessage(errMessage)
	return err
}

/*
 * YAMLFileFormatError
 */
type YAMLFileFormatError struct {
	FileError
}

func NewYAMLFileFormatError(fpath string, errorMessage interface{}) *YAMLFileFormatError {
	var err = &YAMLFileFormatError{}
	err.SetErrorType(ERROR_YAML_FILE_FORMAT_ERROR)
	err.SetCallerByStackFrameSkip(2)
	err.SetErrorFilePath(fpath)
	err.SetMessage(errorMessage)
	return err
}

/*
 * ParameterTypeMismatchError
 */
type ParameterTypeMismatchError struct {
	FileError
	Parameter    string
	ExpectedType string
	ActualType   string
}

func NewParameterTypeMismatchError(fpath string, param string, expectedType string, actualType string) *ParameterTypeMismatchError {
	var err = &ParameterTypeMismatchError{
		ExpectedType: expectedType,
		ActualType:   actualType,
	}

	err.SetErrorType(ERROR_YAML_PARAMETER_TYPE_MISMATCH)
	err.SetCallerByStackFrameSkip(2)
	err.SetErrorFilePath(fpath)
	err.SetMessageFormat("%s [%s]: %s %s: [%s], %s: [%s]")
	str := fmt.Sprintf(err.MessageFormat,
		STR_PARAMETER, param,
		STR_TYPE,
		STR_EXPECTED, expectedType,
		STR_ACTUAL, actualType)
	err.SetMessage(str)
	return err
}

/*
 * InvalidParameterType
 */
type InvalidParameterTypeError struct {
	FileError
	Parameter  string
	ActualType string
}

func NewInvalidParameterTypeError(fpath string, param string, actualType string) *ParameterTypeMismatchError {
	var err = &ParameterTypeMismatchError{
		ActualType: actualType,
	}
	err.SetErrorFilePath(fpath)
	err.SetErrorType(ERROR_YAML_INVALID_PARAMETER_TYPE)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessageFormat("%s [%s]: %s [%s]")
	str := fmt.Sprintf(err.MessageFormat,
		STR_PARAMETER, param,
		STR_TYPE, actualType)
	err.SetMessage(str)
	return err
}

/*
 * YAMLParserErr
 */
type YAMLParserError struct {
	FileError
	lines []string
	msgs  []string
}

func NewYAMLParserErr(fpath string, msg interface{}) *YAMLParserError {
	var err = &YAMLParserError{}
	err.SetErrorType(ERROR_YAML_PARSER_ERROR)
	err.SetErrorFilePath(fpath)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessage(msg)
	return err
}

/*
 * InvalidRuntime
 */
type InvalidRuntimeError struct {
	FileError
	Runtime           string
	SupportedRuntimes []string
}

func NewInvalidRuntimeError(errMessage string, fpath string, action string, runtime string, supportedRuntimes []string) *InvalidRuntimeError {
	var err = &InvalidRuntimeError{
		SupportedRuntimes: supportedRuntimes,
	}
	err.SetErrorFilePath(fpath)
	err.SetErrorType(ERROR_YAML_INVALID_RUNTIME)
	err.SetCallerByStackFrameSkip(2)
	str := fmt.Sprintf("%s %s [%s]: %s [%s]: %s [%s]",
		errMessage,
		STR_ACTION, action,
		STR_RUNTIME, runtime,
		STR_SUPPORTED_RUNTIMES, strings.Join(supportedRuntimes, ", "))
	err.SetMessage(str)
	return err
}

/*
 * InvalidWebExport
 */
type InvalidWebExportError struct {
	FileError
	Webexport           string
	SupportedWebexports []string
}

func NewInvalidWebExportError(fpath string, action string, webexport string, supportedWebexports []string) *InvalidWebExportError {
	var err = &InvalidWebExportError{
		SupportedWebexports: supportedWebexports,
	}
	err.SetErrorFilePath(fpath)
	err.SetErrorType(ERROR_YAML_INVALID_WEB_EXPORT)
	err.SetCallerByStackFrameSkip(2)
	str := fmt.Sprintf("%s [%s]: %s [%s]: %s [%s]",
		STR_ACTION, action,
		STR_WEB_EXPORT, webexport,
		STR_SUPPORTED_WEB_EXPORTS, strings.Join(supportedWebexports, ", "))
	err.SetMessage(str)
	return err
}

/*
 * Invalid API Gateway Method
 */
type InvalidAPIGatewayMethodError struct {
	FileError
	method           string
	SupportedMethods []string
}

func NewInvalidAPIGatewayMethodError(fpath string, api string, method string, supportedMethods []string) *InvalidAPIGatewayMethodError {
	var err = &InvalidAPIGatewayMethodError{
		SupportedMethods: supportedMethods,
	}
	err.SetErrorFilePath(fpath)
	err.SetErrorType(ERROR_YAML_INVALID_API_GATEWAY_METHOD)
	err.SetCallerByStackFrameSkip(2)
	str := fmt.Sprintf("%s [%s]: %s [%s]: %s [%s]",
		STR_API, api,
		STR_API_METHOD, method,
		STR_API_SUPPORTED_METHODS, strings.Join(supportedMethods, ", "))
	err.SetMessage(str)
	return err
}

/*
 * Invalid Web Action API
 */
type InvalidWebActionAPIError struct {
	WskDeployBaseErr
}

func NewInvalidWebActionError(apiName string, actionName string, isSequence bool) *InvalidWebActionAPIError {
	var err = &InvalidWebActionAPIError{}

	i18nErrorID := wski18n.ID_ERR_API_MISSING_WEB_ACTION_X_action_X_api_X

	if isSequence {
		i18nErrorID = wski18n.ID_ERR_API_MISSING_WEB_SEQUENCE_X_sequence_X_api_X
	}

	errString := wski18n.T(i18nErrorID,
		map[string]interface{}{
			wski18n.KEY_SEQUENCE: actionName,
			wski18n.KEY_API:      apiName})
	wskprint.PrintOpenWhiskWarning(errString)

	err.SetErrorType(ERROR_YAML_INVALID_API)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessage(errString)
	return err
}

/*
 * Failed to Retrieve/Parse Runtime
 */
type RuntimeParserError struct {
	WskDeployBaseErr
}

func NewRuntimeParserError(errorMsg string) *RuntimeParserError {
	var err = &RuntimeParserError{}
	err.SetErrorType(ERROR_RUNTIME_PARSER_FAILURE)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessage(errorMsg)
	return err
}

/*
 * Failed to Retrieve/Parse Runtime
 */
type DeployError struct {
	WskDeployBaseErr
}

func NewActionSecureKeyError(errorMsg string) *DeployError {
	var err = &DeployError{}
	err.SetErrorType(ERROR_ACTION_ANNOTATION)
	err.SetCallerByStackFrameSkip(2)
	err.SetMessage(errorMsg)
	return err
}

func IsCustomError(err error) bool {

	switch err.(type) {

	case *CommandError:
	case *WhiskClientError:
	case *WhiskClientInvalidConfigError:
	case *FileError:
	case *FileReadError:
	case *ErrorManifestFileNotFound:
	case *YAMLFileFormatError:
	case *ParameterTypeMismatchError:
	case *InvalidParameterTypeError:
	case *YAMLParserError:
		return true
	}
	return false
}

func AppendDetailToErrorMessage(detail string, add string, location int) string {

	if len(detail) == 0 {
		detail = "\n"
	}
	_, fname, lineNum, _ := runtime.Caller(location)
	detail += fmt.Sprintf("  >> %s [%v]: %s", filepath.Base(fname), lineNum, add)
	return detail
}
