// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package oauth2

import (
	"fmt"
	"time"

	"github.com/apache/pulsar-client-go/oauth2/clock"
	"github.com/form3tech-oss/jwt-go"
	"golang.org/x/oauth2"
)

const (
	ClaimNameUserName = "https://pulsar.apache.org/username"
)

// Flow abstracts an OAuth 2.0 authentication and authorization flow
type Flow interface {
	// Authorize obtains an authorization grant based on an OAuth 2.0 authorization flow.
	// The method returns a grant which may contain an initial access token.
	Authorize(audience string) (*AuthorizationGrant, error)
}

// AuthorizationGrantRefresher refreshes OAuth 2.0 authorization grant
type AuthorizationGrantRefresher interface {
	// Refresh refreshes an authorization grant to contain a fresh access token
	Refresh(grant *AuthorizationGrant) (*AuthorizationGrant, error)
}

type AuthorizationGrantType string

const (
	// GrantTypeClientCredentials represents a client credentials grant
	GrantTypeClientCredentials AuthorizationGrantType = "client_credentials"

	// GrantTypeDeviceCode represents a device code grant
	GrantTypeDeviceCode AuthorizationGrantType = "device_code"
)

// AuthorizationGrant is a credential representing the resource owner's authorization
// to access its protected resources, and is used by the client to obtain an access token
type AuthorizationGrant struct {
	// Type describes the type of authorization grant represented by this structure
	Type AuthorizationGrantType `json:"type"`

	// Audience is the intended audience of the access tokens
	Audience string `json:"audience,omitempty"`

	// ClientID is an OAuth2 client identifier used by some flows
	ClientID string `json:"client_id,omitempty"`

	// ClientCredentials is credentials data for the client credentials grant type
	ClientCredentials *KeyFile `json:"client_credentials,omitempty"`

	// the token endpoint
	TokenEndpoint string `json:"token_endpoint"`

	// Token contains an access token in the client credentials grant type,
	// and a refresh token in the device authorization grant type
	Token *oauth2.Token `json:"token,omitempty"`
}

// TokenResult holds token information
type TokenResult struct {
	AccessToken  string `json:"access_token"`
	IDToken      string `json:"id_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int    `json:"expires_in"`
}

// Issuer holds information about the issuer of tokens
type Issuer struct {
	IssuerEndpoint string
	ClientID       string
	Audience       string
}

func convertToOAuth2Token(token *TokenResult, clock clock.Clock) oauth2.Token {
	return oauth2.Token{
		AccessToken:  token.AccessToken,
		TokenType:    "bearer",
		RefreshToken: token.RefreshToken,
		Expiry:       clock.Now().Add(time.Duration(token.ExpiresIn) * time.Second),
	}
}

// ExtractUserName extracts the username claim from an authorization grant
func ExtractUserName(token oauth2.Token) (string, error) {
	p := jwt.Parser{}
	claims := jwt.MapClaims{}
	if _, _, err := p.ParseUnverified(token.AccessToken, claims); err != nil {
		return "", fmt.Errorf("unable to decode the access token: %v", err)
	}
	username, ok := claims[ClaimNameUserName]
	if !ok {
		return "", fmt.Errorf("access token doesn't contain a username claim")
	}
	switch v := username.(type) {
	case string:
		return v, nil
	default:
		return "", fmt.Errorf("access token contains an unsupported username claim")
	}
}
