// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 bufstudioagent

import (
	"bytes"
	"fmt"
	"io"
)

import (
	connect "github.com/bufbuild/connect-go"

	"google.golang.org/protobuf/proto"
)

import (
	"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/protoencoding"
)

// bufferCodec is a connect.Codec for use with clients of type
// connect.Client[bytes.Buffer, bytes.Buffer] which does not attempt to parse
// messages but instead allows the application layer to work on the buffers
// directly. This is useful for creating proxies.
type bufferCodec struct {
	name string
}

var _ connect.Codec = (*bufferCodec)(nil)

func (b *bufferCodec) Name() string { return b.name }

func (b *bufferCodec) Marshal(src any) ([]byte, error) {
	switch typedSrc := src.(type) {
	case *bytes.Buffer:
		return typedSrc.Bytes(), nil
	case proto.Message:
		// When the codec is named "proto", connect will assume that it
		// may also be used to unmarshal the errors in the
		// grpc-status-details-bin trailer. The type used is not
		// exported so we match against the general proto.Message.
		return protoencoding.NewWireMarshaler().Marshal(typedSrc)
	default:
		return nil, fmt.Errorf("marshal unexpected type %T", src)
	}
}

func (b *bufferCodec) Unmarshal(src []byte, dst any) error {
	switch destination := dst.(type) {
	case *bytes.Buffer:
		destination.Reset()
		_, err := io.Copy(destination, bytes.NewReader(src))
		return err
	case proto.Message:
		// When the codec is named "proto", connect will assume that it
		// may also be used to unmarshal the errors in the
		// grpc-status-details-bin trailer. The type used is not
		// exported so we match against the general proto.Message.
		return protoencoding.NewWireUnmarshaler(nil).Unmarshal(src, destination)
	default:
		return fmt.Errorf("unmarshal unexpected type %T", dst)
	}
}
