// Copyright 2019 The Go 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 authorizes programs to make HTTP requests to the discovery site.
package auth

import (
	"context"
	"fmt"
	"net/http"

	"golang.org/x/pkgsite/internal/derrors"
	"google.golang.org/api/idtoken"
)

// OAuth 2.0 Client IDs for the go-discovery (main) and the go-discovery-exp (exp) projects.
// See https://cloud.google.com/iap/docs/authentication-howto for more details.
const (
	mainClientID = "117187402928-nl3u0qo5l2c2hhsuf2qj8irsfb3l6hfc.apps.googleusercontent.com"
	expClientID  = "55665122702-tk2rogkaalgru7pqibvbltqs7geev8j5.apps.googleusercontent.com"
)

// NewClient creates an http.Client for accessing go-discovery services.
// Its first argument is the JSON contents of a service account credentials file.
// If nil, default credentials are used.
// Its second argument determines which client ID to use.
func NewClient(ctx context.Context, jsonCreds []byte, useExp bool) (_ *http.Client, err error) {
	defer derrors.Wrap(&err, "auth.NewClient(jsonCreds, %t)", useExp)
	audience, opts := idtokenArgs(jsonCreds, useExp)
	return idtoken.NewClient(ctx, audience, opts...)
}

// Header returns a header value (typically a Bearer token) to be used in the
// HTTP 'Authorization' header.
func Header(ctx context.Context, jsonCreds []byte, useExp bool) (_ string, err error) {
	defer derrors.Wrap(&err, "auth.Header(jsonCreds, %t)", useExp)

	audience, opts := idtokenArgs(jsonCreds, useExp)
	ts, err := idtoken.NewTokenSource(ctx, audience, opts...)
	if err != nil {
		return "", err
	}
	token, err := ts.Token()
	if err != nil {
		return "", fmt.Errorf("TokenSource.Token(): %v", err)
	}
	// This is a dummy request to get the authorization header.
	req, err := http.NewRequest("GET", "http://localhost", nil)
	if err != nil {
		return "", fmt.Errorf("http.NewRequest(): %v", err)
	}
	token.SetAuthHeader(req)
	return req.Header.Get("Authorization"), nil
}

func idtokenArgs(jsonCreds []byte, useExp bool) (string, []idtoken.ClientOption) {
	var opts []idtoken.ClientOption
	if len(jsonCreds) > 0 {
		opts = append(opts, idtoken.WithCredentialsJSON(jsonCreds))
	}
	audience := mainClientID
	if useExp {
		audience = expClientID
	}
	return audience, opts
}

// NewClient creates an http.Client that adds an Authorization header
// containing its argument as a bearer token.
func NewClientBearer(token string) *http.Client {
	return &http.Client{
		Transport: &HeadersTransport{
			Base: http.DefaultTransport,
			Headers: map[string]string{
				"Authorization": fmt.Sprintf("Bearer %s", token),
			},
		},
	}
}

// HeadersTransport is an http.Transport that adds headers to the request.
type HeadersTransport struct {
	Headers map[string]string
	Base    http.RoundTripper
}

func (t *HeadersTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	// Copy req and its headers.
	newReq := *req
	newReq.Header = make(http.Header)
	for k, v := range req.Header {
		newReq.Header[k] = v
	}
	// Add or overwrite our headers.
	for h, v := range t.Headers {
		newReq.Header.Set(h, v)
	}
	return t.Base.RoundTrip(&newReq)
}
