// Copyright 2016 The LUCI Authors.
//
// 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 auth

import (
	"context"
	"net/http"
)

// NewModifyingTransport returns a transport that can modify headers of
// http.Request's that pass through it (e.g. by appending authentication
// information).
//
// Go docs explicitly prohibit this kind of behavior, but everyone cheat and
// implement it anyway. E.g. https://github.com/golang/oauth2.
//
// Works only with Go >=1.5 transports (that use Request.Cancel instead of
// deprecated Transport.CancelRequest). For same reason doesn't implement
// CancelRequest itself.
//
// TODO(vadimsh): Move it elsewhere. It has no direct relation to auth.
func NewModifyingTransport(base http.RoundTripper, modifier func(*http.Request) error) http.RoundTripper {
	return &modifyingTransport{
		base:     base,
		modifier: modifier,
	}
}

type modifyingTransport struct {
	base     http.RoundTripper
	modifier func(*http.Request) error
}

func (t *modifyingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	clone := *req
	clone.Header = make(http.Header, len(req.Header))
	for k, v := range req.Header {
		clone.Header[k] = v
	}
	if err := t.modifier(&clone); err != nil {
		return nil, err
	}
	return t.base.RoundTrip(&clone)
}

var globalInstrumentTransport func(context.Context, http.RoundTripper, string) http.RoundTripper

// SetMonitoringInstrumentation sets a global callback used by Authenticator to
// add monitoring instrumentation to a transport.
//
// This is used by tsmon library in init(). We have to resort to callbacks to
// break module dependency cycle (tsmon is using auth lib already).
func SetMonitoringInstrumentation(cb func(context.Context, http.RoundTripper, string) http.RoundTripper) {
	globalInstrumentTransport = cb
}
