// Copyright 2017 The Goma 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 auth

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	"sync"
	"time"

	"go.opencensus.io/trace"
	"golang.org/x/oauth2"
	"golang.org/x/sync/singleflight"

	"go.chromium.org/goma/server/auth/enduser"
	"go.chromium.org/goma/server/log"
	authpb "go.chromium.org/goma/server/proto/auth"
	"go.chromium.org/goma/server/rpc"
)

// ErrNoAuthHeader represents authentication failure due to lack of Authorization header in an HTTP request.
var ErrNoAuthHeader = errors.New("no Authorization header")

// ErrInternal represents internal error.
var ErrInternal = errors.New("internal error")

// ErrExpired represents expiration of access token.
var ErrExpired = errors.New("expired")

// ErrOverQuota represents the user used up the quota.
var ErrOverQuota = errors.New("over quota")

type authInfo struct {
	err error
	mu  sync.Mutex // protect resp.Quota

	// TODO: define type to avoid email leak in logging.
	resp *authpb.AuthResp
}

func (ai *authInfo) expiresAt() time.Time {
	if ai.err != nil || ai.resp == nil || ai.resp.ExpiresAt == nil {
		return time.Now().Add(1 * time.Second)
	}
	return time.Unix(ai.resp.ExpiresAt.Seconds, int64(ai.resp.ExpiresAt.Nanos))
}

func (ai *authInfo) String() string {
	return fmt.Sprintf("authInfo:%s %s %s err:%v", ai.resp.GetGroupId(), ai.expiresAt(), ai.resp.GetErrorDescription(), ai.err)
}

// Check returns error if authInfo does not have valid AuthResp.
// This code also checks quota, and decrease remaining quota for accessing
// the service.
func (ai *authInfo) Check(ctx context.Context) error {
	logger := log.FromContext(ctx)
	// check order:
	// 1. authInfo.err == nil?
	// 2. ErrorDescription
	// 3. Email exists.
	// 4. token expiration.
	// 5. Quota > 0 || Quota < 0 (unlimited)
	if ai.err != nil {
		logger.Warnf("auth.Check %v due to %v", ErrInternal, ai.err)
		return ErrInternal
	}
	if ai.resp.ErrorDescription != "" {
		logger.Warnf("permission denied: %s", ai.resp.ErrorDescription)
		return errors.New(ai.resp.ErrorDescription)
	}
	// Valid AuthResp should not make Email empty but it is.
	if ai.resp.Email == "" {
		logger.Warnf("auth.Check %v", ErrInternal)
		return ErrInternal
	}

	expiresAt := ai.expiresAt()
	now := time.Now()
	if expiresAt.Before(now) {
		logger.Warnf("auth.Check %v because token was expired at %v", ErrExpired, expiresAt)
		return ErrExpired
	}

	ai.mu.Lock()
	defer ai.mu.Unlock()
	if ai.resp.Quota < 0 { // unlimited.
		return nil
	}
	if ai.resp.Quota == 0 {
		return ErrOverQuota
	}
	ai.resp.Quota--
	return nil
}

type Auth struct {
	Client authpb.AuthServiceClient
	Retry  rpc.Retry

	sg    singleflight.Group
	mu    sync.Mutex
	cache map[string]*authInfo

	runAt func(time.Time, func())
}

func (a *Auth) scheduledRun(t time.Time, f func()) {
	scheduledRun := a.runAt
	if scheduledRun == nil {
		scheduledRun = runAt
	}
	scheduledRun(t, f)
}

// Check checks authorization header in an HTTP request.
// The function returns error if authentication failed.
// ErrNoAuthHeader is returned if no authorization header is in the request.
func (a *Auth) Check(ctx context.Context, req *http.Request) (*enduser.EndUser, error) {
	ctx, span := trace.StartSpan(ctx, "go.chromium.org/goma/server/auth.Auth.Check")
	defer span.End()
	logger := log.FromContext(ctx)
	logger.Debugf("httprpc.Auth.Check %s", req.URL.Path)

	authorization := req.Header.Get("Authorization")
	if authorization == "" {
		logger.Warnf("no authorization header")
		return nil, ErrNoAuthHeader
	}
	a.mu.Lock()
	if a.cache == nil {
		a.cache = make(map[string]*authInfo)
	}
	ai, ok := a.cache[authorization]
	a.mu.Unlock()
	if !ok {
		v, err, _ := a.sg.Do(authorization, func() (interface{}, error) {
			logger.Debugf("first call for %s...", authorization[:len(authorization)/3])
			ai := &authInfo{}
			err := a.Retry.Do(ctx, func() error {
				var err error
				ai.resp, err = a.Client.Auth(ctx, &authpb.AuthReq{
					Authorization: authorization,
				})
				return err
			})
			if err != nil {
				logger.Errorf("auth failed: %v", err)
				ai.err = err
			}
			go a.scheduledRun(expiryTime(ai.expiresAt()), func() {
				a.mu.Lock()
				delete(a.cache, authorization)
				a.mu.Unlock()
			})
			a.mu.Lock()
			a.cache[authorization] = ai
			a.mu.Unlock()
			return ai, nil
		})
		if err != nil {
			logger.Errorf("auth error: %v", err)
			return nil, err
		}
		ai = v.(*authInfo)
	}
	err := ai.Check(ctx)
	if err != nil {
		logger.Warnf("auth check err: %v", err)
		return nil, err
	}
	token := &oauth2.Token{
		AccessToken: ai.resp.Token.GetAccessToken(),
		TokenType:   ai.resp.Token.GetTokenType(),
	}
	return enduser.New(ai.resp.Email, ai.resp.GroupId, token), nil
}

// Auth authenticates the requests and returns new context with enduser info.
func (a *Auth) Auth(ctx context.Context, req *http.Request) (context.Context, error) {
	u, err := a.Check(ctx, req)
	if err != nil {
		return ctx, err
	}
	return enduser.NewContext(ctx, u), nil
}
