// +build unit

/*
 * 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 (
	"errors"
	"fmt"
	"github.com/stretchr/testify/assert"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

/*
 * TestCustomErrorOutputFormat
 */
func TestCustomErrorOutputFormat(t *testing.T) {

	_, fn, _, _ := runtime.Caller(0)
	packageName := filepath.Base(fn)
	const TEST_DEFAULT_ERROR_MESSAGE = "Some bad error"
	const TEST_COMMAND string = "test"
	const TEST_ERROR_CODE = 400   // Bad request
	const TEST_SUCCESS_CODE = 200 // Good request
	const TEST_EXISTANT_MANIFEST_FILE = "tests/dat/manifest_validate_multiline_params.yaml"
	const TEST_NONEXISTANT_MANIFEST_FILE = "tests/dat/missing_manifest.yaml"
	const TEST_INVALID_YAML_MANIFEST_FILE = "tests/dat/manifest_bad_yaml_invalid_comment.yaml"
	const TEST_PARAM_NAME = "Age"
	const TEST_PARAM_TYPE_INT = "integer"
	const TEST_PARAM_TYPE_FLOAT = "float"
	const TEST_PARAM_TYPE_FOO = "foo"

	/*
	 * CommandError
	 */
	err1 := NewCommandError(TEST_COMMAND, TEST_DEFAULT_ERROR_MESSAGE)
	actualResult := strings.TrimSpace(err1.Error())
	expectedResult := fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
		packageName,
		err1.LineNum,
		ERROR_COMMAND_FAILED,
		STR_COMMAND,
		TEST_COMMAND,
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * WhiskClientError
	 */
	err2 := NewWhiskClientError(TEST_DEFAULT_ERROR_MESSAGE, TEST_ERROR_CODE, nil)
	actualResult = strings.TrimSpace(err2.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: %d: %s",
		packageName,
		err2.LineNum,
		ERROR_WHISK_CLIENT_ERROR,
		STR_ERROR_CODE,
		TEST_ERROR_CODE,
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * WhiskClientError
	 */
	err21 := NewWhiskClientError("", TEST_SUCCESS_CODE, nil)
	actualResult = strings.TrimSpace(err21.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: %d:",
		packageName,
		err21.LineNum,
		ERROR_WHISK_CLIENT_ERROR,
		STR_ERROR_CODE,
		TEST_SUCCESS_CODE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * WhiskClientInvalidConfigError
	 */
	err3 := NewWhiskClientInvalidConfigError(TEST_DEFAULT_ERROR_MESSAGE)
	actualResult = strings.TrimSpace(err3.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s",
		packageName,
		err3.LineNum,
		ERROR_WHISK_CLIENT_INVALID_CONFIG,
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * FileReadError
	 */
	err4 := NewFileReadError(TEST_NONEXISTANT_MANIFEST_FILE, TEST_DEFAULT_ERROR_MESSAGE)
	actualResult = strings.TrimSpace(err4.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: "+STR_FILE+": [%s]: %s",
		packageName,
		err4.LineNum,
		ERROR_FILE_READ_ERROR,
		filepath.Base(TEST_NONEXISTANT_MANIFEST_FILE),
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * ManifestFileNotFoundError
	 */
	err5 := NewErrorManifestFileNotFound(TEST_NONEXISTANT_MANIFEST_FILE, TEST_DEFAULT_ERROR_MESSAGE)
	actualResult = strings.TrimSpace(err5.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
		packageName,
		err5.LineNum,
		ERROR_MANIFEST_FILE_NOT_FOUND,
		STR_FILE,
		filepath.Base(TEST_NONEXISTANT_MANIFEST_FILE),
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * YAMLFileFormatError
	 */
	err6 := NewYAMLFileFormatError(TEST_INVALID_YAML_MANIFEST_FILE, TEST_DEFAULT_ERROR_MESSAGE)
	actualResult = strings.TrimSpace(err6.Error())
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
		packageName,
		err6.LineNum,
		ERROR_YAML_FILE_FORMAT_ERROR,
		STR_FILE,
		filepath.Base(TEST_INVALID_YAML_MANIFEST_FILE),
		TEST_DEFAULT_ERROR_MESSAGE)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * ParameterTypeMismatchError
	 */
	err8 := NewParameterTypeMismatchError(
		TEST_EXISTANT_MANIFEST_FILE,
		TEST_PARAM_NAME,
		TEST_PARAM_TYPE_INT,
		TEST_PARAM_TYPE_FLOAT)
	actualResult = strings.TrimSpace(err8.Error())
	msg8 := fmt.Sprintf("%s [%s]: %s %s: [%s], %s: [%s]",
		STR_PARAMETER, TEST_PARAM_NAME,
		STR_TYPE,
		STR_EXPECTED, TEST_PARAM_TYPE_INT,
		STR_ACTUAL, TEST_PARAM_TYPE_FLOAT)
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
		packageName,
		err8.LineNum,
		ERROR_YAML_PARAMETER_TYPE_MISMATCH,
		STR_FILE,
		filepath.Base(TEST_EXISTANT_MANIFEST_FILE),
		msg8)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * InvalidParameterType
	 */
	err9 := NewInvalidParameterTypeError(TEST_EXISTANT_MANIFEST_FILE, TEST_PARAM_NAME, TEST_PARAM_TYPE_FOO)
	actualResult = strings.TrimSpace(err9.Error())
	msg9 := fmt.Sprintf("%s [%s]: %s [%s]",
		STR_PARAMETER, TEST_PARAM_NAME,
		STR_TYPE, TEST_PARAM_TYPE_FOO)
	expectedResult = fmt.Sprintf("%s [%d]: [%s]: "+STR_FILE+": [%s]: %s",
		packageName,
		err9.LineNum,
		ERROR_YAML_INVALID_PARAMETER_TYPE,
		filepath.Base(TEST_EXISTANT_MANIFEST_FILE),
		msg9)
	assert.Equal(t, expectedResult, actualResult)

	/*
	 * YAMLParserErr
	 */

	// verify that nested (YAML) errors get correctly appended as indented details to the top-level error message
	ERR_YAML_1 := "did not find expected key"
	ERR_YAML_2 := "did not find expected ',' or ']'"
	ERR_YAML_3 := "found duplicate %YAML directive"

	yamlErrors := fmt.Sprintf("%s\n%s\n%s", ERR_YAML_1, ERR_YAML_2, ERR_YAML_3)
	err10 := NewYAMLParserErr(TEST_EXISTANT_MANIFEST_FILE, errors.New(yamlErrors))

	baseErr := NewWskDeployBaseError("type", "fx", 100, "")
	baseErr.appendDetail(ERR_YAML_1)
	baseErr.appendDetail(ERR_YAML_2)
	baseErr.appendDetail(ERR_YAML_3)
	msg := baseErr.GetMessage()

	assert.Equal(t, msg, err10.GetMessage())

}
