// Copyright 2020 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 component_test

import (
	"context"
	"errors"
	"sync"
	"syscall/zx"
	"syscall/zx/fidl"
	"syscall/zx/zxwait"
	"testing"

	"go.fuchsia.dev/fuchsia/src/lib/component"

	"fidl/bindingstest"
)

var _ bindingstest.Test1WithCtx = (*test1Impl)(nil)

type test1Impl struct{}

func (t *test1Impl) Echo(_ fidl.Context, s *string) (*string, error) {
	return s, nil
}

func (t *test1Impl) NoResponse(fidl.Context) error {
	return nil
}

func (t *test1Impl) EmptyResponse(fidl.Context) error {
	return nil
}

func (t *test1Impl) EchoHandleRights(_ fidl.Context, h zx.Port) (uint32, error) {
	infoHandleBasic, err := h.Handle().GetInfoHandleBasic()
	if err != nil {
		return 0, err
	}
	return uint32(infoHandleBasic.Rights), h.Close()
}

func TestEmptyWriteErrors(t *testing.T) {
	var wg sync.WaitGroup

	ch, sh, err := zx.NewChannel(0)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := ch.Close(); err != nil {
			t.Error(err)
		}
		// Wait for the serving goroutine to exit, then confirm that ServeExclusive
		// closed the channel.
		wg.Wait()
		err := sh.Close()
		if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
			return
		}
		t.Errorf("got sh.Close() = %v, want %q", err, zx.ErrBadHandle)
	}()

	errChan := make(chan error, 1)

	wg.Add(1)
	go func() {
		defer wg.Done()
		component.ServeExclusive(context.Background(), &bindingstest.Test1WithCtxStub{
			Impl: &test1Impl{},
		}, sh, func(err error) {
			errChan <- err
		})
	}()

	if err := ch.Write(nil, nil, 0); err != nil {
		t.Fatal(err)
	}

	if _, err := zxwait.Wait(zx.Handle(ch), zx.SignalChannelPeerClosed, zx.TimensecInfinite); err != nil {
		t.Fatal(err)
	}

	close(errChan)
	if err := <-errChan; !errors.Is(err, fidl.ErrPayloadTooSmall) {
		t.Errorf("got ServeExclusive error = %v, want %q", err, fidl.ErrPayloadTooSmall)
	}
}

func TestEcho(t *testing.T) {
	var wg sync.WaitGroup

	ch, sh, err := zx.NewChannel(0)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		// Expect the final test to have closed the client.
		func() {
			err := ch.Close()
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
				return
			}
			t.Errorf("got ch.Close() = %v, want %q", err, zx.ErrBadHandle)
		}()
		// Wait for the serving goroutine to exit, then confirm that ServeExclusive
		// closed the channel.
		wg.Wait()
		func() {
			err := sh.Close()
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
				return
			}
			t.Errorf("got sh.Close() = %v, want %q", err, zx.ErrBadHandle)
		}()
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		component.ServeExclusive(context.Background(), &bindingstest.Test1WithCtxStub{
			Impl: &test1Impl{},
		}, sh, func(err error) {
			t.Error(err)
		})
	}()

	client := bindingstest.Test1WithCtxInterface{Channel: ch}

	t.Run("Basic", func(t *testing.T) {
		str := "Hello World!"
		r, err := client.Echo(context.Background(), &str)
		if err != nil {
			t.Fatal(err)
		}
		if r == nil {
			t.Fatalf("got Echo(%q) = nil", str)
		}
		if *r != str {
			t.Fatalf("got Echo(%q) = %q", str, *r)
		}
	})

	t.Run("NoResponse", func(t *testing.T) {
		if err := client.NoResponse(context.Background()); err != nil {
			t.Fatal(err)
		}
	})

	t.Run("EmptyResponse", func(t *testing.T) {
		if err := client.EmptyResponse(context.Background()); err != nil {
			t.Fatal(err)
		}
	})

	t.Run("Event", func(t *testing.T) {
		const str = "Surprise!"
		pxy := bindingstest.Test1EventProxy{Channel: sh}
		if err := pxy.Surprise(str); err != nil {
			t.Fatal(err)
		}
		s, err := client.ExpectSurprise(context.Background())
		if err != nil {
			t.Fatal(err)
		}
		if s != str {
			t.Fatalf("got Event = %q, want %q", str, s)
		}
	})

	t.Run("ReducingHandleRights", func(t *testing.T) {
		const expectedRights = zx.RightTransfer | zx.RightDuplicate | zx.RightRead
		port, err := zx.NewPort(0)
		if err != nil {
			t.Fatal(err)
		}
		defer func() {
			err := port.Close()
			// Ownership should have moved to the server, and it should have closed
			// the handle.
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
				return
			}
			t.Errorf("got port.Close() = %v, want %q", err, zx.ErrBadHandle)
		}()
		handleInfo, err := port.Handle().GetInfoHandleBasic()
		if err != nil {
			t.Fatal(err)
		}
		if !handleInfo.Rights.StrictSupersetOf(expectedRights) {
			t.Fatalf("got !(%b).StrictSupersetOf(%b)", handleInfo.Rights, expectedRights)
		}
		rights, err := client.EchoHandleRights(context.Background(), port)
		if err != nil {
			t.Fatal(err)
		}
		if rights := zx.Rights(rights); rights != expectedRights {
			t.Fatalf("got EchoHandleRights(...) = %b, want %b", rights, expectedRights)
		}
	})

	t.Run("MissingExpectedRightsSendingSide", func(t *testing.T) {
		// This test tests the sending side when there are missing expected rights.
		// The receiving side is harder to test because there needs to be a
		// mismatch of rights on the sending and receiving side.
		port, err := zx.NewPort(0)
		if err != nil {
			t.Fatal(err)
		}
		defer func() {
			err := port.Close()
			// This handle should have been consumed by the replace below.
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
				return
			}
			t.Errorf("got port.Close() = %v, want %q", err, zx.ErrBadHandle)
		}()
		const reducedRights = zx.RightTransfer | zx.RightDuplicate
		h, err := port.Handle().Replace(reducedRights)
		if err != nil {
			t.Fatal(err)
		}
		defer func() {
			err := h.Close()
			// Ownership should have moved to the server, and it should have closed
			// the handle.
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
				return
			}
			t.Errorf("got h.Close() = %v, want %q", err, zx.ErrBadHandle)
		}()
		handleInfo, err := h.GetInfoHandleBasic()
		if err != nil {
			t.Fatal(err)
		}
		if handleInfo.Rights != reducedRights {
			t.Fatalf("got Rights = %b, want %b", handleInfo.Rights, reducedRights)
		}
		{
			_, err := client.EchoHandleRights(context.Background(), zx.Port(h))
			if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrInvalidArgs {
				return
			}
			t.Fatalf("got EchoHandleRights(reducedRights) = %v, want %q", err, zx.ErrInvalidArgs)
		}
	})
}

func TestServeExclusive_MagicNumberCheck(t *testing.T) {
	var wg sync.WaitGroup

	ch, sh, err := zx.NewChannel(0)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := ch.Close(); err != nil {
			t.Error(err)
		}
		// Wait for the serving goroutine to exit, then confirm that ServeExclusive
		// closed the channel.
		wg.Wait()
		err := sh.Close()
		if err, ok := err.(*zx.Error); ok && err.Status == zx.ErrBadHandle {
			return
		}
		t.Errorf("got sh.Close() = %v, want %q", err, zx.ErrBadHandle)
	}()

	errChan := make(chan error, 1)

	wg.Add(1)
	go func() {
		defer wg.Done()
		component.ServeExclusive(context.Background(), &bindingstest.Test1WithCtxStub{
			Impl: &test1Impl{},
		}, sh, func(err error) {
			errChan <- err
		})
	}()

	// Send an event with an unknown magic number. The method ordinal and message
	// body can also be invalid but magic numbers are checked first.
	request := []byte{
		0, 0, 0, 0, // txid
		0, 0, 0, // flags
		0,                      // magic number
		0, 0, 0, 0, 0, 0, 0, 1, // method ordinal
		0, 0, 0, 0, 0, 0, 0, 0, // empty struct data
	}

	if err := ch.Write(request, nil, 0); err != nil {
		t.Fatal(err)
	}

	if _, err := zxwait.Wait(zx.Handle(ch), zx.SignalChannelPeerClosed, zx.TimensecInfinite); err != nil {
		t.Fatal(err)
	}

	close(errChan)
	if err := <-errChan; !errors.Is(err, fidl.ErrUnknownMagic) {
		t.Errorf("got ServeExclusive error = %v, want %q", err, fidl.ErrUnknownMagic)
	}
}
