package testing

import (
	"net/url"
	"reflect"
	"testing"

	"github.com/gophercloud/gophercloud"
	th "github.com/gophercloud/gophercloud/testhelper"
)

func TestMaybeString(t *testing.T) {
	testString := ""
	var expected *string
	actual := gophercloud.MaybeString(testString)
	th.CheckDeepEquals(t, expected, actual)

	testString = "carol"
	expected = &testString
	actual = gophercloud.MaybeString(testString)
	th.CheckDeepEquals(t, expected, actual)
}

func TestMaybeInt(t *testing.T) {
	testInt := 0
	var expected *int
	actual := gophercloud.MaybeInt(testInt)
	th.CheckDeepEquals(t, expected, actual)

	testInt = 4
	expected = &testInt
	actual = gophercloud.MaybeInt(testInt)
	th.CheckDeepEquals(t, expected, actual)
}

func TestBuildQueryString(t *testing.T) {
	type testVar string
	opts := struct {
		J  int       `q:"j"`
		R  string    `q:"r,required"`
		C  bool      `q:"c"`
		S  []string  `q:"s"`
		TS []testVar `q:"ts"`
		TI []int     `q:"ti"`
	}{
		J:  2,
		R:  "red",
		C:  true,
		S:  []string{"one", "two", "three"},
		TS: []testVar{"a", "b"},
		TI: []int{1, 2},
	}
	expected := &url.URL{RawQuery: "c=true&j=2&r=red&s=one&s=two&s=three&ti=1&ti=2&ts=a&ts=b"}
	actual, err := gophercloud.BuildQueryString(&opts)
	if err != nil {
		t.Errorf("Error building query string: %v", err)
	}
	th.CheckDeepEquals(t, expected, actual)

	opts = struct {
		J  int       `q:"j"`
		R  string    `q:"r,required"`
		C  bool      `q:"c"`
		S  []string  `q:"s"`
		TS []testVar `q:"ts"`
		TI []int     `q:"ti"`
	}{
		J: 2,
		C: true,
	}
	_, err = gophercloud.BuildQueryString(&opts)
	if err == nil {
		t.Errorf("Expected error: 'Required field not set'")
	}
	th.CheckDeepEquals(t, expected, actual)

	_, err = gophercloud.BuildQueryString(map[string]interface{}{"Number": 4})
	if err == nil {
		t.Errorf("Expected error: 'Options type is not a struct'")
	}
}

func TestBuildHeaders(t *testing.T) {
	testStruct := struct {
		Accept string `h:"Accept"`
		Num    int    `h:"Number,required"`
		Style  bool   `h:"Style"`
	}{
		Accept: "application/json",
		Num:    4,
		Style:  true,
	}
	expected := map[string]string{"Accept": "application/json", "Number": "4", "Style": "true"}
	actual, err := gophercloud.BuildHeaders(&testStruct)
	th.CheckNoErr(t, err)
	th.CheckDeepEquals(t, expected, actual)

	testStruct.Num = 0
	_, err = gophercloud.BuildHeaders(&testStruct)
	if err == nil {
		t.Errorf("Expected error: 'Required header not set'")
	}

	_, err = gophercloud.BuildHeaders(map[string]interface{}{"Number": 4})
	if err == nil {
		t.Errorf("Expected error: 'Options type is not a struct'")
	}
}

func TestQueriesAreEscaped(t *testing.T) {
	type foo struct {
		Name  string `q:"something"`
		Shape string `q:"else"`
	}

	expected := &url.URL{RawQuery: "else=Triangl+e&something=blah%2B%3F%21%21foo"}

	actual, err := gophercloud.BuildQueryString(foo{Name: "blah+?!!foo", Shape: "Triangl e"})
	th.AssertNoErr(t, err)

	th.AssertDeepEquals(t, expected, actual)
}

func TestBuildRequestBody(t *testing.T) {
	type PasswordCredentials struct {
		Username string `json:"username" required:"true"`
		Password string `json:"password" required:"true"`
	}

	type TokenCredentials struct {
		ID string `json:"id,omitempty" required:"true"`
	}

	type orFields struct {
		Filler int `json:"filler,omitempty"`
		F1     int `json:"f1,omitempty" or:"F2"`
		F2     int `json:"f2,omitempty" or:"F1"`
	}

	// AuthOptions wraps a gophercloud AuthOptions in order to adhere to the AuthOptionsBuilder
	// interface.
	type AuthOptions struct {
		PasswordCredentials `json:"passwordCredentials,omitempty" xor:"TokenCredentials"`

		// The TenantID and TenantName fields are optional for the Identity V2 API.
		// Some providers allow you to specify a TenantName instead of the TenantId.
		// Some require both. Your provider's authentication policies will determine
		// how these fields influence authentication.
		TenantID   string `json:"tenantId,omitempty"`
		TenantName string `json:"tenantName,omitempty"`

		// TokenCredentials allows users to authenticate (possibly as another user) with an
		// authentication token ID.
		TokenCredentials `json:"token,omitempty" xor:"PasswordCredentials"`

		OrFields orFields `json:"or_fields,omitempty"`
	}

	var successCases = []struct {
		opts     AuthOptions
		expected map[string]interface{}
	}{
		{
			AuthOptions{
				PasswordCredentials: PasswordCredentials{
					Username: "me",
					Password: "swordfish",
				},
			},
			map[string]interface{}{
				"auth": map[string]interface{}{
					"passwordCredentials": map[string]interface{}{
						"password": "swordfish",
						"username": "me",
					},
				},
			},
		},
		{
			AuthOptions{
				TokenCredentials: TokenCredentials{
					ID: "1234567",
				},
			},
			map[string]interface{}{
				"auth": map[string]interface{}{
					"token": map[string]interface{}{
						"id": "1234567",
					},
				},
			},
		},
	}

	for _, successCase := range successCases {
		actual, err := gophercloud.BuildRequestBody(successCase.opts, "auth")
		th.AssertNoErr(t, err)
		th.AssertDeepEquals(t, successCase.expected, actual)
	}

	var failCases = []struct {
		opts     AuthOptions
		expected error
	}{
		{
			AuthOptions{
				TenantID:   "987654321",
				TenantName: "me",
			},
			gophercloud.ErrMissingInput{},
		},
		{
			AuthOptions{
				TokenCredentials: TokenCredentials{
					ID: "1234567",
				},
				PasswordCredentials: PasswordCredentials{
					Username: "me",
					Password: "swordfish",
				},
			},
			gophercloud.ErrMissingInput{},
		},
		{
			AuthOptions{
				PasswordCredentials: PasswordCredentials{
					Password: "swordfish",
				},
			},
			gophercloud.ErrMissingInput{},
		},
		{
			AuthOptions{
				PasswordCredentials: PasswordCredentials{
					Username: "me",
					Password: "swordfish",
				},
				OrFields: orFields{
					Filler: 2,
				},
			},
			gophercloud.ErrMissingInput{},
		},
	}

	for _, failCase := range failCases {
		_, err := gophercloud.BuildRequestBody(failCase.opts, "auth")
		th.AssertDeepEquals(t, reflect.TypeOf(failCase.expected), reflect.TypeOf(err))
	}
}
