// Copyright 2021-2023 Buf Technologies, Inc.
//
// 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 triple is a slim RPC framework built on Protocol Buffers and
// [net/http]. In addition to supporting its own protocol, Triple handlers and
// clients are wire-compatible with gRPC, including streaming.
//
// This documentation is intended to explain each type and function in
// isolation. Walkthroughs, FAQs, and other narrative docs are available on the
// [dubbo-go website], and there's a working [demonstration service] on Github.
//
// [dubbo-go website]: https://cn.dubbo.apache.org/zh-cn/overview/mannual/golang-sdk/
// [demonstration service]: https://github.com/apache/dubbo-go-samples
package triple_protocol

import (
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
)

// Version is the semantic version of the triple module.
const Version = "0.1.0"

// These constants are used in compile-time handshakes with triple's generated
// code.
const (
	IsAtLeastVersion0_0_1 = true
	IsAtLeastVersion0_1_0 = true
	IsAtLeastVersion1_6_0 = true
)

// StreamType describes whether the client, server, neither, or both is
// streaming.
type StreamType uint8

const (
	StreamTypeUnary  StreamType = 0b00
	StreamTypeClient StreamType = 0b01
	StreamTypeServer StreamType = 0b10
	StreamTypeBidi              = StreamTypeClient | StreamTypeServer
)

const (
	tripleServiceGroup   = "tri-service-group"
	tripleServiceVersion = "tri-service-version"
)

// StreamingHandlerConn is the server's view of a bidirectional message
// exchange. Interceptors for streaming RPCs may wrap StreamingHandlerConns.
//
// Like the standard library's [http.ResponseWriter], StreamingHandlerConns write
// response headers to the network with the first call to Send. Any subsequent
// mutations are effectively no-ops. Handlers may mutate response trailers at
// any time before returning. When the client has finished sending data,
// Receive returns an error wrapping [io.EOF]. Handlers should check for this
// using the standard library's [errors.Is].
//
// Headers and trailers beginning with "Triple-" and "Grpc-" are reserved for
// use by the gRPC and Triple protocols: applications may read them but
// shouldn't write them.
//
// StreamingHandlerConn implementations provided by this module guarantee that
// all returned errors can be cast to [*Error] using the standard library's
// [errors.As].
//
// StreamingHandlerConn implementations do not need to be safe for concurrent use.
type StreamingHandlerConn interface {
	Spec() Spec
	Peer() Peer

	Receive(interface{}) error
	RequestHeader() http.Header
	ExportableHeader() http.Header

	Send(interface{}) error
	ResponseHeader() http.Header
	ResponseTrailer() http.Header
}

// StreamingClientConn is the client's view of a bidirectional message exchange.
// Interceptors for streaming RPCs may wrap StreamingClientConn.
//
// StreamingClientConn write request headers to the network with the first
// call to Send. Any subsequent mutations are effectively no-ops. When the
// server is done sending data, the StreamingClientConn's Receive method
// returns an error wrapping [io.EOF]. Clients should check for this using the
// standard library's [errors.Is] or [IsEnded]. If the server encounters an error
// during processing, subsequent calls to the StreamingClientConn's Send method
// will return an error wrapping [io.EOF]; clients may then call Receive to
// unmarshal the error.
//
// Headers and trailers beginning with "Triple-" and "Grpc-" are reserved for
// use by the gRPC and Triple protocols: applications may read them but
// shouldn't write them.
//
// StreamingClientConn implementations provided by this module guarantee that
// all returned errors can be cast to [*Error] using the standard library's
// [errors.As].
//
// In order to support bidirectional streaming RPCs, all StreamingClientConn
// implementations must support limited concurrent use. See the comments on
// each group of methods for details.
type StreamingClientConn interface {
	// Spec and Peer must be safe to call concurrently with all other methods.
	Spec() Spec
	Peer() Peer

	// Send, RequestHeader, and CloseRequest may race with each other, but must
	// be safe to call concurrently with all other methods.
	Send(interface{}) error
	RequestHeader() http.Header
	CloseRequest() error

	// Receive, ResponseHeader, ResponseTrailer, and CloseResponse may race with
	// each other, but must be safe to call concurrently with all other methods.
	Receive(interface{}) error
	ResponseHeader() http.Header
	ResponseTrailer() http.Header
	CloseResponse() error
}

// Request is a wrapper around a generated request message. It provides
// access to metadata like headers and the RPC specification, as well as
// strongly-typed access to the message itself.
type Request struct {
	Msg interface{}

	spec   Spec
	peer   Peer
	header http.Header
}

// NewRequest wraps a generated request message.
func NewRequest(message interface{}) *Request {
	return &Request{
		Msg: message,
		// Initialized lazily so we don't allocate unnecessarily.
		header: nil,
	}
}

// Any returns the concrete request message as an empty interface, so that
// *Request implements the [AnyRequest] interface.
func (r *Request) Any() interface{} {
	return r.Msg
}

// Spec returns a description of this RPC.
func (r *Request) Spec() Spec {
	return r.spec
}

// Peer describes the other party for this RPC.
func (r *Request) Peer() Peer {
	return r.peer
}

// Header returns the HTTP headers for this request. Headers beginning with
// "Triple-" and "Grpc-" are reserved for use by the Triple and gRPC
// protocols: applications may read them but shouldn't write them.
func (r *Request) Header() http.Header {
	if r.header == nil {
		r.header = make(http.Header)
	}
	return r.header
}

// internalOnly implements AnyRequest.
func (r *Request) internalOnly() {}

// AnyRequest is the common method set of every [Request], regardless of type
// parameter. It's used in unary interceptors.
//
// Headers and trailers beginning with "Triple-" and "Grpc-" are reserved for
// use by the gRPC and Triple protocols: applications may read them but
// shouldn't write them.
//
// To preserve our ability to add methods to this interface without breaking
// backward compatibility, only types defined in this package can implement
// AnyRequest.
type AnyRequest interface {
	Any() interface{}
	Spec() Spec
	Peer() Peer
	Header() http.Header

	internalOnly()
}

// Response is a wrapper around a generated response message. It provides
// access to metadata like headers and trailers, as well as strongly-typed
// access to the message itself.
type Response struct {
	Msg interface{}

	header  http.Header
	trailer http.Header
}

// NewResponse wraps a generated response message.
func NewResponse(message interface{}) *Response {
	return &Response{
		Msg: message,
		// Initialized lazily so we don't allocate unnecessarily.
		header:  nil,
		trailer: nil,
	}
}

// Any returns the concrete response message as an empty interface, so that
// *Response implements the [AnyResponse] interface.
func (r *Response) Any() interface{} {
	return r.Msg
}

// Header returns the HTTP headers for this response. Headers beginning with
// "Triple-" and "Grpc-" are reserved for use by the Triple and gRPC
// protocols: applications may read them but shouldn't write them.
func (r *Response) Header() http.Header {
	if r.header == nil {
		r.header = make(http.Header)
	}
	return r.header
}

// Trailer returns the trailers for this response. Depending on the underlying
// RPC protocol, trailers may be sent as HTTP trailers or a protocol-specific
// block of in-body metadata.
//
// Trailers beginning with "Triple-" and "Grpc-" are reserved for use by the
// Triple and gRPC protocols: applications may read them but shouldn't write
// them.
func (r *Response) Trailer() http.Header {
	if r.trailer == nil {
		r.trailer = make(http.Header)
	}
	return r.trailer
}

// internalOnly implements AnyResponse.
func (r *Response) internalOnly() {}

// AnyResponse is the common method set of every [Response], regardless of type
// parameter. It's used in unary interceptors.
//
// Headers and trailers beginning with "Triple-" and "Grpc-" are reserved for
// use by the Triple and Grpc protocols: applications may read them but
// shouldn't write them.
//
// To preserve our ability to add methods to this interface without breaking
// backward compatibility, only types defined in this package can implement
// AnyResponse.
type AnyResponse interface {
	Any() interface{}
	Header() http.Header
	Trailer() http.Header

	internalOnly()
}

// HTTPClient is the interface triple expects HTTP clients to implement. The
// standard library's *http.Client implements HTTPClient.
type HTTPClient interface {
	Do(*http.Request) (*http.Response, error)
}

// Spec is a description of a client call or a handler invocation.
//
// If you're using Protobuf, protoc-gen-triple-go generates a constant for the
// fully-qualified Procedure corresponding to each RPC in your schema.
type Spec struct {
	StreamType       StreamType
	Procedure        string // for example, "/acme.foo.v1.FooService/Bar"
	IsClient         bool   // otherwise we're in a handler
	IdempotencyLevel IdempotencyLevel
}

// Peer describes the other party to an RPC.
//
// When accessed client-side, Addr contains the host or host:port from the
// server's URL. When accessed server-side, Addr contains the client's address
// in IP:port format.
//
// On both the client and the server, Protocol is the RPC protocol in use.
// Currently, it's either [ProtocolTriple], [ProtocolGRPC], or
// todo: Should we support ProtocolGRPCWeb?
// [ProtocolGRPCWeb], but additional protocols may be added in the future.
//
// Query contains the query parameters for the request. For the server, this
// will reflect the actual query parameters sent. For the client, it is unset.
type Peer struct {
	Addr     string
	Protocol string
	Query    url.Values // server-only
}

func newPeerFromURL(url *url.URL, protocol string) Peer {
	return Peer{
		Addr:     url.Host,
		Protocol: protocol,
	}
}

// handlerConnCloser extends HandlerConn with a method for handlers to
// terminate the message exchange (and optionally send an error to the client).
type handlerConnCloser interface {
	StreamingHandlerConn

	Close(error) error
}

// receiveUnaryResponse unmarshals a message from a StreamingClientConn, then
// envelopes the message and attaches headers and trailers. It attempts to
// consume the response stream and is not appropriate when receiving multiple
// messages.
func receiveUnaryResponse(conn StreamingClientConn, response AnyResponse) error {
	resp, ok := response.(*Response)
	if !ok {
		panic(fmt.Sprintf("response %T is not of Response type", response))
	}
	if err := conn.Receive(resp.Msg); err != nil {
		return err
	}
	// In a well-formed stream, the response message may be followed by a block
	// of in-stream trailers or HTTP trailers. To ensure that we receive the
	// trailers, try to read another message from the stream.
	if err := conn.Receive(resp.Msg); err == nil {
		return NewError(CodeUnknown, errors.New("unary stream has multiple messages"))
	} else if err != nil && !errors.Is(err, io.EOF) {
		return NewError(CodeUnknown, err)
	}
	resp.header = conn.ResponseHeader()
	resp.trailer = conn.ResponseTrailer()
	return nil
}

// IsEnded is a convenient function indicating the end of stream. It is introduced to not expose
// io.EOF to beginners. Please refer to https://github.com/apache/dubbo-go/pull/2416#discussion_r1318558801
func IsEnded(err error) bool {
	return errors.Is(err, io.EOF)
}
