/*
 * 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"
	"runtime"
	"strings"
	"path/filepath"
	"net/http"
	"io/ioutil"
)

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"

	// 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"
)

/*
 * 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")
		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
}

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
}
