// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The protoreflect tag disables fast-path methods, including legacy ones.
// +build !protoreflect

package proto_test

import (
	"bytes"
	"errors"
	"fmt"
	"testing"

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

type selfMarshaler struct {
	bytes []byte
	err   error
}

func (m selfMarshaler) Reset()        {}
func (m selfMarshaler) ProtoMessage() {}

func (m selfMarshaler) String() string {
	return fmt.Sprintf("selfMarshaler{bytes:%v, err:%v}", m.bytes, m.err)
}

func (m selfMarshaler) Marshal() ([]byte, error) {
	return m.bytes, m.err
}

func (m *selfMarshaler) Unmarshal(b []byte) error {
	m.bytes = b
	return m.err
}

func TestLegacyMarshalMethod(t *testing.T) {
	for _, test := range []selfMarshaler{
		{bytes: []byte("marshal")},
		{bytes: []byte("marshal"), err: errors.New("some error")},
	} {
		m := impl.Export{}.MessageOf(test).Interface()
		b, err := proto.Marshal(m)
		if err != test.err || !bytes.Equal(b, test.bytes) {
			t.Errorf("proto.Marshal(%v) = %v, %v; want %v, %v", test, b, err, test.bytes, test.err)
		}
		if gotSize, wantSize := proto.Size(m), len(test.bytes); gotSize != wantSize {
			t.Fatalf("proto.Size(%v) = %v, want %v", test, gotSize, wantSize)
		}

		prefix := []byte("prefix")
		want := append(prefix, test.bytes...)
		b, err = proto.MarshalOptions{}.MarshalAppend(prefix, m)
		if err != test.err || !bytes.Equal(b, want) {
			t.Errorf("MarshalAppend(%v, %v) = %v, %v; want %v, %v", prefix, test, b, err, test.bytes, test.err)
		}
	}
}

func TestLegacyUnmarshalMethod(t *testing.T) {
	sm := &selfMarshaler{}
	m := impl.Export{}.MessageOf(sm).Interface()
	want := []byte("unmarshal")
	if err := proto.Unmarshal(want, m); err != nil {
		t.Fatalf("proto.Unmarshal(selfMarshaler{}) = %v, want nil", err)
	}
	if !bytes.Equal(sm.bytes, want) {
		t.Fatalf("proto.Unmarshal(selfMarshaler{}): Marshal method not called")
	}
}
