// Copyright 2017 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 trace

import (
	"net/http"
)

// Transport is an http.RoundTripper that traces the outgoing requests.
//
// Transport is safe for concurrent usage.
//
// Deprecated: see https://cloud.google.com/trace/docs/setup/go.
type Transport struct {
	// Base is the base http.RoundTripper to be used to do the actual request.
	//
	// Optional. If nil, http.DefaultTransport is used.
	Base http.RoundTripper
}

// RoundTrip creates a trace.Span and inserts it into the outgoing request's headers.
// The created span can follow a parent span, if a parent is presented in
// the request's context.
//
// Deprecated: see https://cloud.google.com/trace/docs/setup/go.
func (t Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	span := FromContext(req.Context()).NewRemoteChild(req)
	resp, err := t.base().RoundTrip(req)

	// TODO(jbd): Is it possible to defer the span.Finish?
	// In cases where RoundTrip panics, we still can finish the span.
	span.Finish(WithResponse(resp))
	return resp, err
}

// CancelRequest cancels an in-flight request by closing its connection.
//
// Deprecated: see https://cloud.google.com/trace/docs/setup/go.
func (t Transport) CancelRequest(req *http.Request) {
	type canceler interface {
		CancelRequest(*http.Request)
	}
	if cr, ok := t.base().(canceler); ok {
		cr.CancelRequest(req)
	}
}

func (t Transport) base() http.RoundTripper {
	if t.Base != nil {
		return t.Base
	}
	return http.DefaultTransport
}

// HTTPHandler returns a http.Handler from the given handler
// that is aware of the incoming request's span.
// The span can be extracted from the incoming request in handler
// functions from incoming request's context:
//
//    span := trace.FromContext(r.Context())
//
// The span will be auto finished by the handler.
//
// Deprecated: see https://cloud.google.com/trace/docs/setup/go.
func (c *Client) HTTPHandler(h http.Handler) http.Handler {
	if c == nil {
		return h
	}
	return &handler{traceClient: c, handler: h}
}

type handler struct {
	traceClient *Client
	handler     http.Handler
}

// Deprecated: see https://cloud.google.com/trace/docs/setup/go.
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	traceID, parentSpanID, options, optionsOk, ok := traceInfoFromHeader(r.Header.Get(httpHeader))
	if !ok {
		traceID = nextTraceID()
	}
	t := &trace{
		traceID:       traceID,
		client:        h.traceClient,
		globalOptions: options,
		localOptions:  options,
	}
	span := startNewChildWithRequest(r, t, parentSpanID)
	span.span.Kind = spanKindServer
	span.rootSpan = true
	configureSpanFromPolicy(span, h.traceClient.policy, ok)
	defer span.Finish()

	r = r.WithContext(NewContext(r.Context(), span))
	if ok && !optionsOk {
		// Inject the trace context back to the response with the sampling options.
		// TODO(jbd): Remove when there is a better way to report the client's sampling.
		w.Header().Set(httpHeader, spanHeader(traceID, parentSpanID, span.trace.localOptions))
	}
	h.handler.ServeHTTP(w, r)
}
