package connection

import (
	"context"
	"fmt"
	"time"

	"github.com/sirupsen/logrus"
	rpc "zombiezen.com/go/capnproto2/rpc"

	"github.com/cloudflare/cloudflared/h2mux"
	"github.com/cloudflare/cloudflared/tunnelrpc"
	tunnelpogs "github.com/cloudflare/cloudflared/tunnelrpc/pogs"
)

// NewRPCClient creates and returns a new RPC client, which will communicate
// using a stream on the given muxer
func NewRPCClient(
	ctx context.Context,
	muxer *h2mux.Muxer,
	logger *logrus.Entry,
	openStreamTimeout time.Duration,
) (client tunnelpogs.TunnelServer_PogsClient, err error) {
	openStreamCtx, openStreamCancel := context.WithTimeout(ctx, openStreamTimeout)
	defer openStreamCancel()
	stream, err := muxer.OpenRPCStream(openStreamCtx)
	if err != nil {
		return
	}

	if !isRPCStreamResponse(stream.Headers) {
		stream.Close()
		err = fmt.Errorf("rpc: bad response headers: %v", stream.Headers)
		return
	}

	conn := rpc.NewConn(
		tunnelrpc.NewTransportLogger(logger, rpc.StreamTransport(stream)),
		tunnelrpc.ConnLog(logger),
	)
	client = tunnelpogs.TunnelServer_PogsClient{Client: conn.Bootstrap(ctx), Conn: conn}
	return client, nil
}

func isRPCStreamResponse(headers []h2mux.Header) bool {
	return len(headers) == 1 &&
		headers[0].Name == ":status" &&
		headers[0].Value == "200"
}
