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

package fidl_test

import (
	"fmt"
	"reflect"
	"strings"
	"syscall/zx"
	"syscall/zx/fidl"
	"syscall/zx/fidl/internal/bindingstest"
	"testing"
)

var testCtx fidl.MarshalerContext

type example struct {
	name       string
	input      fidl.Message
	expectSize int
}

// general provides test cases used to verify correctness, and
// benchmark against.
//
// Keep these as a slice to preserve consistent ordering when running.
func general() []example {
	h0, h1, err := zx.NewChannel(0)
	if err != nil {
		panic(fmt.Sprintf("failed to create channel: %s", err))
	}
	defer func() {
		if err := h0.Close(); err != nil {
			panic(fmt.Sprintf("failed to close channel: %s", err))
		}
		if err := h1.Close(); err != nil {
			panic(fmt.Sprintf("failed to close channel: %s", err))
		}
	}()

	return []example{
		// TODO(https://fxbug.dev/42158433): Here we're checking the special logic adapting channels to
		// `request<P>` or `P` representations. This is not supported by GIDL yet.
		{"interface1", &bindingstest.TestInterface1{
			A: bindingstest.Test1WithCtxInterface(fidl.ChannelProxy{Channel: h0}),
			B: bindingstest.Test1WithCtxInterface(fidl.ChannelProxy{Channel: zx.Channel(zx.HandleInvalid)}),
			C: bindingstest.Test1WithCtxInterfaceRequest(fidl.InterfaceRequest{Channel: h1}),
			D: bindingstest.Test1WithCtxInterfaceRequest(fidl.InterfaceRequest{
				Channel: zx.Channel(zx.HandleInvalid),
			}),
		}, 16},
	}
}

func check(t *testing.T, input fidl.Message, expectSize int) {
	t.Helper()
	var respb [zx.ChannelMaxMessageBytes]byte
	var resphd [zx.ChannelMaxMessageHandles]zx.HandleDisposition
	nb, nh, err := fidl.Marshal(testCtx, input, respb[:], resphd[:])
	if err != nil {
		t.Fatalf("marshal: failed: %s", err)
	}
	if nb != expectSize {
		t.Fatalf("marshal: expected size %d but got %d: %s", expectSize, nb, respb[:nb])
	}
	var resphi [zx.ChannelMaxMessageHandles]zx.HandleInfo
	for i := 0; i < nh; i++ {
		resphi[i] = zx.HandleInfo{
			Handle: resphd[i].Handle,
			Type:   resphd[i].Type,
			Rights: resphd[i].Rights,
		}
	}
	output := makeDefault(reflect.TypeOf(input))
	err = fidl.Unmarshal(testCtx, respb[:nb], resphi[:nh], output)
	if err != nil {
		t.Fatalf("unmarshal: failed: %s", err)
	}
	if !reflect.DeepEqual(input, output) {
		t.Fatalf("unmarshal: expected: %#v, got: %#v", input, output)
	}
}

func TestCorrectness(t *testing.T) {
	for _, ex := range general() {
		t.Run(ex.name, func(t *testing.T) {
			check(t, ex.input, ex.expectSize)
		})
	}
}

// This is a specific test checking that the marshaler construction properly
// fails with a clear error message if fed incorrect generated code. Hence,
// this has to stay a hand written test.
func TestFailureNullableTable(t *testing.T) {
	type TestNullableTable struct {
		_ struct{}                  `fidl:"s"`
		A *bindingstest.SimpleTable `fidl:"0" fidl_offset_v2:"0"`
	}
	_, err := fidl.CreateMarshaler(TestNullableTable{})
	if err == nil {
		t.Fatalf("expected error creating marshaler for nullable table")
	}
	if !strings.Contains(err.Error(), "optional field marshaler") {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

// TODO(https://fxbug.dev/42141063): Move to GIDL once we support protocol handles.
func TestConformanceClientEnd(t *testing.T) {
	successCase{
		name:    "handles-clientend",
		context: testCtx,
		input: &bindingstest.HasClientEnd{
			ClientEnd: bindingstest.ExampleProtocolWithCtxInterface(fidl.ChannelProxy{
				Channel: zx.Channel(0x44332211),
			}),
		},
		bytes: []byte{
			0xff, 0xff, 0xff, 0xff, // handle present
			0x00, 0x00, 0x00, 0x00, // padding
		},
		handleInfos: []zx.HandleInfo{
			{
				Handle: zx.Handle(0x44332211),
				Rights: fidl.ProtocolRights,
				Type:   zx.ObjTypeChannel,
			},
		},
		checkRights: true,
	}.check(t)
}

// TODO(https://fxbug.dev/42141063): Move to GIDL once we support protocol handles.
func TestConformanceServerEnd(t *testing.T) {
	successCase{
		name:    "handles-serverend",
		context: testCtx,
		input: &bindingstest.HasServerEnd{
			ServerEnd: bindingstest.ExampleProtocolWithCtxInterfaceRequest(fidl.InterfaceRequest{
				Channel: zx.Channel(0x44332211),
			}),
		},
		bytes: []byte{
			0xff, 0xff, 0xff, 0xff, // handle present
			0x00, 0x00, 0x00, 0x00, // padding
		},
		handleInfos: []zx.HandleInfo{
			{
				Handle: zx.Handle(0x44332211),
				Rights: fidl.ProtocolRights,
				Type:   zx.ObjTypeChannel,
			},
		},
		checkRights: true,
	}.check(t)
}
