package oauth2

import (
	"strings"
	"testing"
)

func TestNewClientID(t *testing.T) {
	newClientID := NewClientID()
	if len(newClientID) != clientIDLength {
		t.Errorf("NewClientID() = %v, want %v", len(newClientID), clientIDLength)
	}
	// check if the characters are valid
	for _, c := range newClientID {
		if !strings.Contains(validClientCharacters, string(c)) {
			t.Errorf("NewClientID() go invalid character %s", string(c))
			break
		}
	}
}

func TestNewClientSecret(t *testing.T) {
	newClientSecret := NewClientSecret()
	if len(newClientSecret) != clientSecretLength {
		t.Errorf("NewClientSecret() = %v, want %v", len(newClientSecret), clientSecretLength)
	}
	// check if the characters are valid
	for _, c := range newClientSecret {
		if !strings.Contains(validClientCharacters, string(c)) {
			t.Errorf("NewClientSecret() go invalid character %s", string(c))
			break
		}
	}
}

func TestNewUserCode(t *testing.T) {
	newUserCode := NewUserCode()
	// genrated user code should be 8 characters with a dash
	if len(newUserCode) != (userCodeLength + 1) {
		t.Errorf("NewUserCode() = %v, want %v", len(newUserCode), userCodeLength)
	}
	userCode := strings.Replace(newUserCode, "-", "", -1)
	// check if the characters are valid
	for _, c := range userCode {
		if !strings.Contains(validUserCharacters, string(c)) {
			t.Errorf("NewUserCode() go invalid character %s", string(c))
			break
		}
	}
}

func TestNewDeviceCode(t *testing.T) {
	newDeviceCode := NewDeviceCode()
	if len(newDeviceCode) != deviceCodeLength {
		t.Errorf("NewDeviceCode() = %v, want %v", len(newDeviceCode), deviceCodeLength)
	}
	// check if the characters are valid
	for _, c := range newDeviceCode {
		if !strings.Contains(validDeviceCharacters, string(c)) {
			t.Errorf("NewDeviceCode() go invalid character %s", string(c))
			break
		}
	}
}

func TestNewAccessToken(t *testing.T) {
	newAccessToken := NewAccessToken()
	expectedLength := tokenLength + len(accessTokenPrefix)
	if len(newAccessToken) != expectedLength {
		t.Errorf("NewAccessToken() = %v, want %v", len(newAccessToken), expectedLength)
	}
	// check prefix
	if !strings.HasPrefix(newAccessToken, accessTokenPrefix) {
		t.Errorf("NewAccessToken() = %v, want %v", newAccessToken, accessTokenPrefix)
	}
	// remove prefix
	rawAccessToken := strings.TrimPrefix(newAccessToken, accessTokenPrefix)
	// check if the characters are valid
	for _, c := range rawAccessToken {
		if !strings.Contains(validClientCharacters, string(c)) {
			t.Errorf("NewAccessToken() go invalid character %s", string(c))
			break
		}
	}
}

func TestNewRefreshToken(t *testing.T) {
	newRefreshToken := NewRefreshToken()
	expectedLength := tokenLength + len(refreshTokenPrefix)
	if len(newRefreshToken) != expectedLength {
		t.Errorf("NewRefreshToken() = %v, want %v", len(newRefreshToken), expectedLength)
	}
	// check prefix
	if !strings.HasPrefix(newRefreshToken, refreshTokenPrefix) {
		t.Errorf("NewRefreshToken() = %v, want %v", newRefreshToken, refreshTokenPrefix)
	}
	// remove prefix
	rawRefreshToken := strings.TrimPrefix(newRefreshToken, refreshTokenPrefix)
	// check if the characters are valid
	for _, c := range rawRefreshToken {
		if !strings.Contains(validClientCharacters, string(c)) {
			t.Errorf("NewRefreshToken() go invalid character %s", string(c))
			break
		}
	}
}
