// +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 whisk

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"net/http"
	"net/url"
	"os"
	"testing"
)

const (
	FakeHost        = "myUrl.com"
	FakeHostDiff    = "myUrlTest.com"
	FakeBaseURL     = "https://" + FakeHost + "/api"
	FakeBaseURLDiff = "https://" + FakeHostDiff + "/api"
	FakeNamespace   = "my_namespace"
	FakeAuthKey     = "dhajfhshfs:hjhfsjfdjfjsgfjs"
)

func GetValidConfigTest() *Config {
	var config Config
	config.Host = FakeHost
	config.Namespace = FakeNamespace
	config.AuthToken = FakeAuthKey
	return &config
}

func GetInvalidConfigMissingApiHostTest() *Config {
	var config Config
	config.Namespace = FakeNamespace
	config.AuthToken = FakeAuthKey
	return &config
}

func GetInvalidConfigMissingApiHostWithBaseURLTest() *Config {
	var config Config
	urlBase := fmt.Sprintf("https://%s/api", FakeHostDiff)
	config.BaseURL, _ = url.Parse(urlBase)
	config.Namespace = FakeNamespace
	config.AuthToken = FakeAuthKey
	return &config
}

func GetValidConfigDiffApiHostAndBaseURLTest() *Config {
	var config Config
	urlBase := fmt.Sprintf("https://%s/api", FakeHostDiff)
	config.BaseURL, _ = url.Parse(urlBase)
	config.Host = FakeHost
	config.Namespace = FakeNamespace
	config.AuthToken = FakeAuthKey
	return &config
}

func TestNewClient(t *testing.T) {
	// Test the use case to pass a valid config.
	config := GetValidConfigTest()
	client, err := NewClient(http.DefaultClient, config)
	assert.Nil(t, err)
	assert.NotNil(t, client)
	assert.Equal(t, FakeNamespace, client.Config.Namespace)
	assert.Equal(t, FakeHost, client.Config.Host)
	assert.Equal(t, FakeBaseURL, client.Config.BaseURL.String())
	assert.Equal(t, FakeAuthKey, client.Config.AuthToken)

	// Test the use case to pass an invalid config with a missing api host.
	config = GetInvalidConfigMissingApiHostTest()
	client, err = NewClient(http.DefaultClient, config)
	assert.NotNil(t, err)
	assert.Contains(t, err.Error(), "Unable to create request URL, because OpenWhisk API host is missing")
	assert.Nil(t, client)

	// Test the use case to pass a valid config with the base url but without api host.
	config = GetInvalidConfigMissingApiHostWithBaseURLTest()
	client, err = NewClient(http.DefaultClient, config)
	assert.NotNil(t, err)
	assert.Contains(t, err.Error(), "Unable to create request URL, because OpenWhisk API host is missing")
	assert.Nil(t, client)

	// Test the use case to pass a valid config with both the base and api host of different values.
	config = GetValidConfigDiffApiHostAndBaseURLTest()
	client, err = NewClient(http.DefaultClient, config)
	assert.Nil(t, err)
	assert.NotNil(t, client)
	assert.Equal(t, FakeNamespace, client.Config.Namespace)
	assert.Equal(t, FakeHost, client.Config.Host)
	assert.Equal(t, FakeBaseURLDiff, client.Config.BaseURL.String())
	assert.Equal(t, FakeAuthKey, client.Config.AuthToken)
}

func TestProxyHost(t *testing.T) {
	var proxyhost = "one.bad.url.going.nowhere.org"
	var proxyurl = "https://" + proxyhost

	config := GetValidConfigTest()
	client, err := NewClient(nil, config)
	assert.NotNil(t, client)

	// This will update the transport
	err = client.LoadX509KeyPair()
	assert.Nil(t, err, "LoadX509KeyPair() failed")

	req, err := client.NewRequest("GET", config.BaseURL.String(), nil, false)
	assert.Nil(t, err, "NewRequest for proxy test failed.")
	if err != nil {
		fmt.Printf("NewRequest() error: %s\n", err.Error())
	}

	// Proxy is enabled by setting env
	if priorProxyEnv, priorProxyEnvSet := os.LookupEnv("HTTPS_PROXY"); priorProxyEnvSet {
		err = os.Unsetenv("HTTPS_PROXY")
		assert.Nil(t, err, "Unsetenv(HTTPS_PROXY) failed: "+err.Error())
		defer os.Setenv("HTTPS_PROXY", priorProxyEnv)
	}
	os.Setenv("HTTPS_PROXY", proxyurl)

	// Issue request that should fail due to a bad proxy host
	_, err = client.Do(req, nil, true)
	assert.NotNil(t, err, "Do() did not fail with invalid proxy URL.")
	if err != nil {
		assert.Contains(t, err.Error(), proxyhost, "Setting HTTPS_PROXY to '"+proxyhost+"' did not cause the CLI to use that proxy URL.")
	}
}

func TestAdditionalHeaders(t *testing.T) {
	config := GetValidConfigTest()
	config.AdditionalHeaders = make(map[string][]string)
	config.AdditionalHeaders.Add("Key1", "Value1")
	config.AdditionalHeaders.Add("Key2", "Value2")

	client, _ := NewClient(nil, config)
	assert.NotNil(t, client)

	newRequest, newRequestErr := client.NewRequest("GET", config.BaseURL.String(), nil, false)
	assert.Nil(t, newRequestErr, "NewRequest for proxy test failed.")
	if newRequestErr != nil {
		fmt.Printf("NewRequest() error: %s\n", newRequestErr.Error())
	}

	assert.Equal(t, "Value1", newRequest.Header.Get("Key1"))
	assert.Equal(t, "Value2", newRequest.Header.Get("Key2"))

	newRequestUrl, newRequestUrlErr := client.NewRequestUrl("GET", config.BaseURL, nil, false, false, "", false)
	assert.Nil(t, newRequestUrlErr, "NewRequest for proxy test failed.")
	if newRequestUrlErr != nil {
		fmt.Printf("NewRequest() error: %s\n", newRequestUrlErr.Error())
	}

	assert.Equal(t, "Value1", newRequestUrl.Header.Get("Key1"))
	assert.Equal(t, "Value2", newRequestUrl.Header.Get("Key2"))
}
