package app

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type auth0TokenResponse struct {
	AccessToken string
	TokenType   string
}

const tokenURL = "https://taxnexus.auth0.com/oauth/token" //nolint:gosec // false positive
const tokenTimeout = 86400 * time.Second
const requestTemplate = `
{
	"client_id": "%s",
	"client_secret": "%s"
	"audience": "%s",
	"grant_type": "client_credentials"
}
`

var accessToken string
var authTokenTime time.Time

// GetAuth0AccessToken uses conf file values to get an Auth0 access token
func GetAuth0AccessToken() string {
	if time.Now().Before(authTokenTime) && accessToken != "" {
		return accessToken
	}
	serviceAccount := GetServiceAccount("auth0")
	payload := strings.NewReader(
		fmt.Sprintf(requestTemplate,
			serviceAccount.ClientID,
			serviceAccount.ClientSecret,
			serviceAccount.Endpoint.Scheme+"://"+
				serviceAccount.Endpoint.Host+
				serviceAccount.Endpoint.BasePath) + "/")
	req, err := http.NewRequest("POST", tokenURL, payload)
	if err != nil {
		return ""
	}
	req.Header.Add("content-type", "application/json")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return ""
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return ""
	}
	var response *auth0TokenResponse
	err = json.Unmarshal(body, response)
	if err != nil {
		return ""
	}
	accessToken = response.AccessToken
	authTokenTime = time.Now().Add(tokenTimeout)
	return accessToken
}
