// Copyright 2015 The Vanadium 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 lib

import (
	"errors"
	"fmt"
	"sync"

	"v.io/v23/context"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/vdl"
	"v.io/v23/vom"
)

type clientWithTimesCalled interface {
	rpc.Client
	TimesCalled(method string) int
}

// NewSimpleClient creates a new mocked rpc client where the given map of method name
// to outputs is used for evaluating the method calls.
// It also adds some testing features such as counters for number of times a method is called
func newSimpleClient(methodsResults map[string][]interface{}) clientWithTimesCalled {
	return &simpleMockClient{
		results:     methodsResults,
		timesCalled: make(map[string]int),
	}
}

// simpleMockClient implements rpc.Client
type simpleMockClient struct {
	// Protects timesCalled
	sync.Mutex

	// results is a map of method names to results
	results map[string][]interface{}
	// timesCalled is a counter for number of times StartCall is called on a specific method name
	timesCalled map[string]int
}

// TimesCalled returns number of times the given method has been called.
func (c *simpleMockClient) TimesCalled(method string) int {
	return c.timesCalled[method]
}

// StartCall Implements rpc.Client
func (c *simpleMockClient) StartCall(ctx *context.T, name, method string, args []interface{}, opts ...rpc.CallOpt) (rpc.ClientCall, error) {
	results, ok := c.results[method]
	if !ok {
		return nil, fmt.Errorf("method %s not found", method)
	}

	// Copy the results so that they can be modified without effecting the original.
	// This must be done via vom encode and decode rather than a direct deep copy because (among other reasons)
	// reflect-based deep copy on vdl.Type objects will fail because of their private fields. This is not a problem with vom
	// as it manually creates the type objects. It is also more realistic to use the same mechanism as the ultimate calls.
	vomBytes, err := vom.Encode(results)
	if err != nil {
		panic(fmt.Sprintf("Error copying value with vom (failed on encode): %v", err))
	}
	var copiedResults []interface{}
	if err := vom.Decode(vomBytes, &copiedResults); err != nil {
		panic(fmt.Sprintf("Error copying value with vom (failed on decode): %v", err))
	}

	clientCall := mockCall{
		results: copiedResults,
	}

	c.Lock()
	c.timesCalled[method]++
	c.Unlock()

	return &clientCall, nil
}

func (c *simpleMockClient) Call(ctx *context.T, name, method string, inArgs, outArgs []interface{}, callOpts ...rpc.CallOpt) error {
	call, err := c.StartCall(ctx, name, method, inArgs, callOpts...)
	if err != nil {
		return err
	}
	return call.Finish(outArgs...)
}

// Close implements rpc.Client
func (*simpleMockClient) Close() {
}

func (*simpleMockClient) Closed() <-chan struct{} {
	return nil
}

// mockCall implements rpc.ClientCall
type mockCall struct {
	mockStream
	results []interface{}
}

// Cancel implements rpc.ClientCall
func (*mockCall) Cancel() {
}

// CloseSend implements rpc.ClientCall
func (*mockCall) CloseSend() error {
	return nil
}

// Finish implements rpc.ClientCall
func (mc *mockCall) Finish(resultptrs ...interface{}) error {
	if got, want := len(resultptrs), len(mc.results); got != want {
		return errors.New(fmt.Sprintf("wrong number of output results; expected resultptrs of size %d but got %d", want, got))
	}
	for ax, res := range resultptrs {
		if mc.results[ax] != nil {
			if err := vdl.Convert(res, mc.results[ax]); err != nil {
				panic(fmt.Sprintf("Error converting out argument %#v: %v", mc.results[ax], err))
			}
		}
	}
	return nil
}

// RemoteBlessings implements rpc.ClientCall
func (*mockCall) RemoteBlessings() ([]string, security.Blessings) {
	return []string{}, security.Blessings{}
}

//mockStream implements rpc.Stream
type mockStream struct{}

//Send implements rpc.Stream
func (*mockStream) Send(interface{}) error {
	return nil
}

//Recv implements rpc.Stream
func (*mockStream) Recv(interface{}) error {
	return nil
}
