/*
 *
 * Copyright 2015 gRPC 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 grpc

import (
	"bytes"
	"fmt"
	"io"
	"net"
	"strings"
	"sync"
	"time"
)

// EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package.
// This should only be set before any RPCs are sent or received by this program.
var EnableTracing bool

// methodFamily returns the trace family for the given method.
// It turns "/pkg.Service/GetFoo" into "pkg.Service".
func methodFamily(m string) string {
	m = strings.TrimPrefix(m, "/") // remove leading slash
	if i := strings.Index(m, "/"); i >= 0 {
		m = m[:i] // remove everything from second slash
	}
	return m
}

// traceEventLog mirrors golang.org/x/net/trace.EventLog.
//
// It exists in order to avoid importing x/net/trace on grpcnotrace builds.
type traceEventLog interface {
	Printf(format string, a ...any)
	Errorf(format string, a ...any)
	Finish()
}

// traceLog mirrors golang.org/x/net/trace.Trace.
//
// It exists in order to avoid importing x/net/trace on grpcnotrace builds.
type traceLog interface {
	LazyLog(x fmt.Stringer, sensitive bool)
	LazyPrintf(format string, a ...any)
	SetError()
	SetRecycler(f func(any))
	SetTraceInfo(traceID, spanID uint64)
	SetMaxEvents(m int)
	Finish()
}

// traceInfo contains tracing information for an RPC.
type traceInfo struct {
	tr        traceLog
	firstLine firstLine
}

// firstLine is the first line of an RPC trace.
// It may be mutated after construction; remoteAddr specifically may change
// during client-side use.
type firstLine struct {
	mu         sync.Mutex
	client     bool // whether this is a client (outgoing) RPC
	remoteAddr net.Addr
	deadline   time.Duration // may be zero
}

func (f *firstLine) SetRemoteAddr(addr net.Addr) {
	f.mu.Lock()
	f.remoteAddr = addr
	f.mu.Unlock()
}

func (f *firstLine) String() string {
	f.mu.Lock()
	defer f.mu.Unlock()

	var line bytes.Buffer
	io.WriteString(&line, "RPC: ")
	if f.client {
		io.WriteString(&line, "to")
	} else {
		io.WriteString(&line, "from")
	}
	fmt.Fprintf(&line, " %v deadline:", f.remoteAddr)
	if f.deadline != 0 {
		fmt.Fprint(&line, f.deadline)
	} else {
		io.WriteString(&line, "none")
	}
	return line.String()
}

const truncateSize = 100

func truncate(x string, l int) string {
	if l > len(x) {
		return x
	}
	return x[:l]
}

// payload represents an RPC request or response payload.
type payload struct {
	sent bool // whether this is an outgoing payload
	msg  any  // e.g. a proto.Message
	// TODO(dsymonds): add stringifying info to codec, and limit how much we hold here?
}

func (p payload) String() string {
	if p.sent {
		return truncate(fmt.Sprintf("sent: %v", p.msg), truncateSize)
	}
	return truncate(fmt.Sprintf("recv: %v", p.msg), truncateSize)
}

type fmtStringer struct {
	format string
	a      []any
}

func (f *fmtStringer) String() string {
	return fmt.Sprintf(f.format, f.a...)
}

type stringer string

func (s stringer) String() string { return string(s) }
