// Copyright 2022 Google LLC
//
// Licensed 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 jwt

import (
	"fmt"
	"time"
)

const (
	jwtMaxClockSkewMinutes = 10
)

// ValidatorOpts define validation options for JWT validators.
type ValidatorOpts struct {
	ExpectedTypeHeader *string
	ExpectedIssuer     *string
	ExpectedAudience   *string

	IgnoreTypeHeader bool
	IgnoreAudiences  bool
	IgnoreIssuer     bool

	AllowMissingExpiration bool
	ExpectIssuedInThePast  bool

	ClockSkew time.Duration
	FixedNow  time.Time

	// Deprecated: Use ExpectedAudience instead.
	ExpectedAudiences *string
}

// Validator defines how JSON Web Tokens (JWT) should be validated.
type Validator struct {
	opts ValidatorOpts
}

// NewValidator creates a new Validator.
func NewValidator(opts *ValidatorOpts) (*Validator, error) {
	if opts == nil {
		return nil, fmt.Errorf("ValidatorOpts can't be nil")
	}
	if opts.ExpectedAudiences != nil {
		if opts.ExpectedAudience != nil {
			return nil, fmt.Errorf("ExpectedAudiences and ExpectedAudience can't be set at the same time")
		}
		opts.ExpectedAudience = opts.ExpectedAudiences
		opts.ExpectedAudiences = nil
	}
	if opts.ExpectedTypeHeader != nil && opts.IgnoreTypeHeader {
		return nil, fmt.Errorf("ExpectedTypeHeader and IgnoreTypeHeader cannot be used together")
	}
	if opts.ExpectedIssuer != nil && opts.IgnoreIssuer {
		return nil, fmt.Errorf("ExpectedIssuer and IgnoreIssuer cannot be used together")
	}
	if opts.ExpectedAudience != nil && opts.IgnoreAudiences {
		return nil, fmt.Errorf("ExpectedAudience and IgnoreAudience cannot be used together")
	}
	if opts.ClockSkew.Minutes() > jwtMaxClockSkewMinutes {
		return nil, fmt.Errorf("clock skew too large, max is %d minutes", jwtMaxClockSkewMinutes)
	}
	return &Validator{
		opts: *opts,
	}, nil
}

// Validate validates a rawJWT according to the options provided.
func (v *Validator) Validate(rawJWT *RawJWT) error {
	if rawJWT == nil {
		return fmt.Errorf("rawJWT can't be nil")
	}
	if err := v.validateTimestamps(rawJWT); err != nil {
		return err
	}
	if err := v.validateTypeHeader(rawJWT); err != nil {
		return fmt.Errorf("validating type header: %v", err)
	}
	if err := v.validateAudiences(rawJWT); err != nil {
		return fmt.Errorf("validating audience claim: %v", err)
	}
	if err := v.validateIssuer(rawJWT); err != nil {
		return fmt.Errorf("validating issuer claim: %v", err)
	}
	return nil
}

func (v *Validator) validateTimestamps(rawJWT *RawJWT) error {
	now := time.Now()
	if !v.opts.FixedNow.IsZero() {
		now = v.opts.FixedNow
	}

	if !rawJWT.HasExpiration() && !v.opts.AllowMissingExpiration {
		return fmt.Errorf("token doesn't have an expiration set")
	}
	if rawJWT.HasExpiration() {
		exp, err := rawJWT.ExpiresAt()
		if err != nil {
			return err
		}
		if !exp.After(now.Add(-v.opts.ClockSkew)) {
			return errJwtExpired
		}
	}
	if rawJWT.HasNotBefore() {
		nbf, err := rawJWT.NotBefore()
		if err != nil {
			return err
		}
		if nbf.After(now.Add(v.opts.ClockSkew)) {
			return fmt.Errorf("token cannot be used yet")
		}
	}
	if v.opts.ExpectIssuedInThePast {
		iat, err := rawJWT.IssuedAt()
		if err != nil {
			return err
		}
		if iat.After(now.Add(v.opts.ClockSkew)) {
			return fmt.Errorf("token has an invalid iat claim in the future")
		}
	}
	return nil
}

func (v *Validator) validateTypeHeader(rawJWT *RawJWT) error {
	skip, err := validateFieldPresence(v.opts.IgnoreTypeHeader, rawJWT.HasTypeHeader(), v.opts.ExpectedTypeHeader != nil)
	if err != nil {
		return err
	}
	if skip {
		return nil
	}
	typeHeader, err := rawJWT.TypeHeader()
	if err != nil {
		return err
	}
	if typeHeader != *v.opts.ExpectedTypeHeader {
		return fmt.Errorf("wrong 'type header' type")
	}
	return nil
}

func (v *Validator) validateIssuer(rawJWT *RawJWT) error {
	skip, err := validateFieldPresence(v.opts.IgnoreIssuer, rawJWT.HasIssuer(), v.opts.ExpectedIssuer != nil)
	if err != nil {
		return err
	}
	if skip {
		return nil
	}
	issuer, err := rawJWT.Issuer()
	if err != nil {
		return err
	}
	if issuer != *v.opts.ExpectedIssuer {
		return fmt.Errorf("got %s, want %s", issuer, *v.opts.ExpectedIssuer)
	}
	return nil
}

func (v *Validator) validateAudiences(rawJWT *RawJWT) error {
	skip, err := validateFieldPresence(v.opts.IgnoreAudiences, rawJWT.HasAudiences(), v.opts.ExpectedAudience != nil)
	if err != nil {
		return err
	}
	if skip {
		return nil
	}
	audiences, err := rawJWT.Audiences()
	if err != nil {
		return err
	}
	for i, aud := range audiences {
		if aud == *v.opts.ExpectedAudience {
			break
		}
		if i == len(audiences)-1 {
			return fmt.Errorf("%s not found", *v.opts.ExpectedAudience)
		}
	}
	return nil
}

func validateFieldPresence(ignore bool, isPresent bool, isExpected bool) (bool, error) {
	if ignore {
		return true, nil
	}
	if !isExpected && !isPresent {
		return true, nil
	}
	if !isExpected && isPresent {
		return false, fmt.Errorf("token has claim but validator doesn't expect it")
	}
	if isExpected && !isPresent {
		return false, fmt.Errorf("claim was expected but isn't present")
	}
	return false, nil
}
