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

import (
	"os"
	"reflect"
	"strings"
)

// Test if a string
func isValidEnvironmentVar(value string) bool {

	// A valid Env. variable should start with or contain '$' (dollar) char.
	//
	// If the value is a single Env. variable, it should start with a '$' (dollar) char
	// and have at least 1 additional character after it, e.g. $ENV_VAR
	// If the value is a concatenation of a string and a Env. variable, it should contain '$' (dollar)
	// and have a string following which is surrounded with '{' and '}', e.g. xxx${ENV_VAR}xxx.
	if value != "" && strings.HasPrefix(value, "$") && len(value) > 1 {
		return true
	}
	if value != "" && strings.Contains(value, "${") && strings.Count(value, "{") == strings.Count(value, "}") {
		return true
	}
	return false
}

// Get the env variable value by key.
// Get the env variable if the key is start by $
// Replace all occurrences of env. variables in the input string
func InterpolateStringWithEnvVar(key interface{}) interface{} {
	// Assure the key itself is not nil
	if key == nil {
		return nil
	}

	if reflect.TypeOf(key).String() == "string" {
		keystr := key.(string)
		if isValidEnvironmentVar(keystr) {
			// retrieve the value of the env. var. from the host system.
			var thisValue string
			//split the string with ${}
			//test if the substr is a environment var
			//if it is, replace it with the value
			f := func(c rune) bool {
				return c == '$' || c == '{' || c == '}'
			}
			for _, substr := range strings.FieldsFunc(keystr, f) {
				//if the substr is a $${ENV_VAR}
				// return ${ENV_VAR}
				if strings.Contains(keystr, "$${"+substr+"}") {
					keystr = strings.Replace(keystr, "$${"+substr+"}", "${"+substr+"}", -1)
					//if the substr is a $ENV_VAR
					// return interpolated string using env. variable
				} else if strings.Contains(keystr, "$"+substr) {
					thisValue = os.Getenv(substr)
					// TODO(920) disabling the warning for now, since we want to get rid of it eventually
					// TODO(920) please add/remove this based on what we decide in issue #920
					//if thisValue == "" {
					// TODO(797) i18n
					//wskprint.PrintlnOpenWhiskWarning("Missing Environment Variable " + substr + ".")
					//}
					keystr = strings.Replace(keystr, "$"+substr, thisValue, -1)
					//if the substr is a ${ENV_VAR}
					// return interpolated string using env. variable
				} else if strings.Contains(keystr, "${"+substr+"}") {
					thisValue = os.Getenv(substr)
					// TODO(920) disabling the warning for now, since we want to get rid of it eventually
					// TODO(920) please add/remove this based on what we decide in issue #920
					//if thisValue == "" {
					// TODO(797) i18n
					//wskprint.PrintlnOpenWhiskWarning("Missing Environment Variable " + substr + ".")
					//}
					keystr = strings.Replace(keystr, "${"+substr+"}", thisValue, -1)
				}
			}
			return keystr
		}

		// The key was not a valid env. variable, simply return it as the value itself (of type string)
		return keystr
	}
	return key
}

// Convert a string name with environment variables into
// the new string with env variables replaced
func ConvertSingleName(theName string) string {
	if len(theName) != 0 {
		theNameEnv := InterpolateStringWithEnvVar(theName)
		if str, ok := theNameEnv.(string); ok {
			return str
		} else {
			return theName
		}
	}
	return theName
}

func GetEnvVarName(name string) string {
	name = strings.Replace(name, "$", "", 1)
	name = strings.Replace(name, "{", "", -1)
	name = strings.Replace(name, "}", "", -1)
	return name

}
