// Copyright 2016 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 google

import (
	"bytes"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"strings"
	"sync"
	"testing"
	"time"

	"golang.org/x/oauth2/jws"
)

var (
	privateKey *rsa.PrivateKey
	jsonKey    []byte
	once       sync.Once
)

func TestJWTAccessTokenSourceFromJSON(t *testing.T) {
	setupDummyKey(t)

	ts, err := JWTAccessTokenSourceFromJSON(jsonKey, "audience")
	if err != nil {
		t.Fatalf("JWTAccessTokenSourceFromJSON: %v\nJSON: %s", err, string(jsonKey))
	}

	tok, err := ts.Token()
	if err != nil {
		t.Fatalf("Token: %v", err)
	}

	if got, want := tok.TokenType, "Bearer"; got != want {
		t.Errorf("TokenType = %q, want %q", got, want)
	}
	if got := tok.Expiry; tok.Expiry.Before(time.Now()) {
		t.Errorf("Expiry = %v, should not be expired", got)
	}

	err = jws.Verify(tok.AccessToken, &privateKey.PublicKey)
	if err != nil {
		t.Errorf("jws.Verify on AccessToken: %v", err)
	}

	claim, err := jws.Decode(tok.AccessToken)
	if err != nil {
		t.Fatalf("jws.Decode on AccessToken: %v", err)
	}

	if got, want := claim.Iss, "gopher@developer.gserviceaccount.com"; got != want {
		t.Errorf("Iss = %q, want %q", got, want)
	}
	if got, want := claim.Sub, "gopher@developer.gserviceaccount.com"; got != want {
		t.Errorf("Sub = %q, want %q", got, want)
	}
	if got, want := claim.Aud, "audience"; got != want {
		t.Errorf("Aud = %q, want %q", got, want)
	}

	// Finally, check the header private key.
	parts := strings.Split(tok.AccessToken, ".")
	hdrJSON, err := base64.RawURLEncoding.DecodeString(parts[0])
	if err != nil {
		t.Fatalf("base64 DecodeString: %v\nString: %q", err, parts[0])
	}
	var hdr jws.Header
	if err := json.Unmarshal(hdrJSON, &hdr); err != nil {
		t.Fatalf("json.Unmarshal: %v (%q)", err, hdrJSON)
	}

	if got, want := hdr.KeyID, "268f54e43a1af97cfc71731688434f45aca15c8b"; got != want {
		t.Errorf("Header KeyID = %q, want %q", got, want)
	}
}

func TestJWTAccessTokenSourceWithScope(t *testing.T) {
	setupDummyKey(t)

	ts, err := JWTAccessTokenSourceWithScope(jsonKey, "scope1", "scope2")
	if err != nil {
		t.Fatalf("JWTAccessTokenSourceWithScope: %v\nJSON: %s", err, string(jsonKey))
	}

	tok, err := ts.Token()
	if err != nil {
		t.Fatalf("Token: %v", err)
	}

	if got, want := tok.TokenType, "Bearer"; got != want {
		t.Errorf("TokenType = %q, want %q", got, want)
	}
	if got := tok.Expiry; tok.Expiry.Before(time.Now()) {
		t.Errorf("Expiry = %v, should not be expired", got)
	}

	err = jws.Verify(tok.AccessToken, &privateKey.PublicKey)
	if err != nil {
		t.Errorf("jws.Verify on AccessToken: %v", err)
	}

	claim, err := jws.Decode(tok.AccessToken)
	if err != nil {
		t.Fatalf("jws.Decode on AccessToken: %v", err)
	}

	if got, want := claim.Iss, "gopher@developer.gserviceaccount.com"; got != want {
		t.Errorf("Iss = %q, want %q", got, want)
	}
	if got, want := claim.Sub, "gopher@developer.gserviceaccount.com"; got != want {
		t.Errorf("Sub = %q, want %q", got, want)
	}
	if got, want := claim.Scope, "scope1 scope2"; got != want {
		t.Errorf("Aud = %q, want %q", got, want)
	}

	// Finally, check the header private key.
	parts := strings.Split(tok.AccessToken, ".")
	hdrJSON, err := base64.RawURLEncoding.DecodeString(parts[0])
	if err != nil {
		t.Fatalf("base64 DecodeString: %v\nString: %q", err, parts[0])
	}
	var hdr jws.Header
	if err := json.Unmarshal(hdrJSON, &hdr); err != nil {
		t.Fatalf("json.Unmarshal: %v (%q)", err, hdrJSON)
	}

	if got, want := hdr.KeyID, "268f54e43a1af97cfc71731688434f45aca15c8b"; got != want {
		t.Errorf("Header KeyID = %q, want %q", got, want)
	}
}

func setupDummyKey(t *testing.T) {
	once.Do(func() {
		// Generate a key we can use in the test data.
		pk, err := rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			t.Fatal(err)
		}
		privateKey = pk
		// Encode the key and substitute into our example JSON.
		enc := pem.EncodeToMemory(&pem.Block{
			Type:  "PRIVATE KEY",
			Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
		})
		enc, err = json.Marshal(string(enc))
		if err != nil {
			t.Fatalf("json.Marshal: %v", err)
		}
		jsonKey = bytes.Replace(jwtJSONKey, []byte(`"super secret key"`), enc, 1)
	})
}
