// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package externalaccount

import (
	"context"
	"encoding/json"
	"golang.org/x/oauth2"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
)

var auth = ClientAuthentication{
	AuthStyle:    oauth2.AuthStyleInHeader,
	ClientID:     clientID,
	ClientSecret: clientSecret,
}

var tokenRequest = STSTokenExchangeRequest{
	ActingParty: struct {
		ActorToken     string
		ActorTokenType string
	}{},
	GrantType:          "urn:ietf:params:oauth:grant-type:token-exchange",
	Resource:           "",
	Audience:           "32555940559.apps.googleusercontent.com", //TODO: Make sure audience is correct in this test (might be mismatched)
	Scope:              []string{"https://www.googleapis.com/auth/devstorage.full_control"},
	RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token",
	SubjectToken:       "Sample.Subject.Token",
	SubjectTokenType:   "urn:ietf:params:oauth:token-type:jwt",
}

var requestbody = "audience=32555940559.apps.googleusercontent.com&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&requested_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdevstorage.full_control&subject_token=Sample.Subject.Token&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt"
var responseBody = `{"access_token":"Sample.Access.Token","issued_token_type":"urn:ietf:params:oauth:token-type:access_token","token_type":"Bearer","expires_in":3600,"scope":"https://www.googleapis.com/auth/cloud-platform"}`
var expectedToken = STSTokenExchangeResponse{
	AccessToken:     "Sample.Access.Token",
	IssuedTokenType: "urn:ietf:params:oauth:token-type:access_token",
	TokenType:       "Bearer",
	ExpiresIn:       3600,
	Scope:           "https://www.googleapis.com/auth/cloud-platform",
	RefreshToken:    "",
}

func TestExchangeToken(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != "POST" {
			t.Errorf("Unexpected request method, %v is found", r.Method)
		}
		if r.URL.String() != "/" {
			t.Errorf("Unexpected request URL, %v is found", r.URL)
		}
		if got, want := r.Header.Get("Authorization"), "Basic cmJyZ25vZ25yaG9uZ28zYmk0Z2I5Z2hnOWc6bm90c29zZWNyZXQ="; got != want {
			t.Errorf("Unexpected authorization header, got %v, want %v", got, want)
		}
		if got, want := r.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; got != want {
			t.Errorf("Unexpected Content-Type header, got %v, want %v", got, want)
		}
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Errorf("Failed reading request body: %v.", err)
		}
		if got, want := string(body), requestbody; got != want {
			t.Errorf("Unexpected exchange payload, got %v but want %v", got, want)
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(responseBody))
	}))
	defer ts.Close()

	headers := http.Header{}
	headers.Add("Content-Type", "application/x-www-form-urlencoded")

	resp, err := ExchangeToken(context.Background(), ts.URL, &tokenRequest, auth, headers, nil)
	if err != nil {
		t.Fatalf("ExchangeToken failed with error: %v", err)
	}

	if expectedToken != *resp {
		t.Errorf("mismatched messages received by mock server.  \nWant: \n%v\n\nGot:\n%v", expectedToken, *resp)
	}

}

func TestExchangeToken_Err(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte("what's wrong with this response?"))
	}))
	defer ts.Close()

	headers := http.Header{}
	headers.Add("Content-Type", "application/x-www-form-urlencoded")
	_, err := ExchangeToken(context.Background(), ts.URL, &tokenRequest, auth, headers, nil)
	if err == nil {
		t.Errorf("Expected handled error; instead got nil.")
	}
}

/* Lean test specifically for options, as the other features are tested earlier. */
type testOpts struct {
	First  string `json:"first"`
	Second string `json:"second"`
}

var optsValues = [][]string{{"foo", "bar"}, {"cat", "pan"}}

func TestExchangeToken_Opts(t *testing.T) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Fatalf("Failed reading request body: %v.", err)
		}
		data, err := url.ParseQuery(string(body))
		if err != nil {
			t.Fatalf("Failed to parse request body: %v", err)
		}
		strOpts, ok := data["options"]
		if !ok {
			t.Errorf("Server didn't recieve an \"options\" field.")
		} else if len(strOpts) < 1 {
			t.Errorf("\"options\" field has length 0.")
		}
		var opts map[string]interface{}
		err = json.Unmarshal([]byte(strOpts[0]), &opts)
		if len(opts) < 2 {
			t.Errorf("Too few options received.")
		}

		val, ok := opts["one"]
		if !ok {
			t.Errorf("Couldn't find first option parameter.")
		} else {
			tOpts1, ok := val.(map[string]interface{})
			if !ok {
				t.Errorf("Failed to assert the first option parameter as type testOpts.")
			} else {
				if got, want := tOpts1["first"].(string), optsValues[0][0]; got != want {
					t.Errorf("First value in first options field is incorrect; got %v but want %v", got, want)
				}
				if got, want := tOpts1["second"].(string), optsValues[0][1]; got != want {
					t.Errorf("Second value in first options field is incorrect; got %v but want %v", got, want)
				}
			}
		}

		val2, ok := opts["two"]
		if !ok {
			t.Errorf("Couldn't find second option parameter.")
		} else {
			tOpts2, ok := val2.(map[string]interface{})
			if !ok {
				t.Errorf("Failed to assert the second option parameter as type testOpts.")
			} else {
				if got, want := tOpts2["first"].(string), optsValues[1][0]; got != want {
					t.Errorf("First value in second options field is incorrect; got %v but want %v", got, want)
				}
				if got, want := tOpts2["second"].(string), optsValues[1][1]; got != want {
					t.Errorf("Second value in second options field is incorrect; got %v but want %v", got, want)
				}
			}
		}

		// Send a proper reply so that no other errors crop up.
		w.Header().Set("Content-Type", "application/json")
		w.Write([]byte(responseBody))

	}))
	defer ts.Close()
	headers := http.Header{}
	headers.Add("Content-Type", "application/x-www-form-urlencoded")

	firstOption := testOpts{optsValues[0][0], optsValues[0][1]}
	secondOption := testOpts{optsValues[1][0], optsValues[1][1]}
	inputOpts := make(map[string]interface{})
	inputOpts["one"] = firstOption
	inputOpts["two"] = secondOption
	ExchangeToken(context.Background(), ts.URL, &tokenRequest, auth, headers, inputOpts)
}
