package main

import (
	"fmt"
	"log"
	"strings"

	"v.io/v23/context"
	"v.io/v23/rpc"

	"mojo/public/go/application"
	"mojo/public/go/bindings"
	"mojo/public/go/system"

	"v.io/v23/vdl"
	"v.io/v23/vdlroot/signature"
	"v.io/x/mojo/transcoder"

	"mojo/public/interfaces/bindings/mojom_types"
	"mojo/public/interfaces/bindings/service_describer"
)

// As long as fakeService meets the Invoker interface, it is allowed to pass as
// a universal v23 service.
// See the function objectToInvoker in v.io/x/ref/runtime/internal/rpc/server.go
type fakeService struct {
	appctx application.Context
	suffix string
	router *bindings.Router
	ids    bindings.Counter
}

// Prepare is used by the Fake Service to prepare the placeholders for the
// input data.
func (fs fakeService) Prepare(ctx *context.T, method string, numArgs int) (argptrs []interface{}, tags []*vdl.Value, _ error) {
	inargs := make([]*vdl.Value, numArgs)
	inptrs := make([]interface{}, len(inargs))
	for i := range inargs {
		inptrs[i] = &inargs[i]
	}
	return inptrs, nil, nil
}

// Wraps the interface request and the name of the requested mojo service.
type v23ServiceRequest struct {
	request bindings.InterfaceRequest
	name    string
}

func (v *v23ServiceRequest) Name() string {
	return v.name
}

func (v *v23ServiceRequest) ServiceDescription() service_describer.ServiceDescription {
	panic("not supported")
}

func (v *v23ServiceRequest) PassMessagePipe() system.MessagePipeHandle {
	return v.request.PassMessagePipe()
}

// Invoke calls the mojom service based on the suffix and converts the mojom
// results (a struct) to Vanadium results (a slice of *vdl.Value).
// Note: The argptrs from Prepare are reused here. The vom bytes should have
// been decoded into these argptrs, so there are actual values inside now.
func (fs fakeService) Invoke(ctx *context.T, call rpc.StreamServerCall, method string, argptrs []interface{}) (results []interface{}, _ error) {
	// fs.suffix consists of the mojo url and the application/interface name.
	// The last part should be the name; everything else is the url.
	parts := strings.Split(fs.suffix, "/")
	mojourl := strings.Join(parts[:len(parts)-1], "/") // e.g., mojo:go_remote_echo_server. May be defined in a BUILD.gn file.
	mojoname := parts[len(parts)-1]                    // e.g., mojo::examples::RemoteEcho. Defined from the interface + module.

	// Create the generic message pipe. r is a bindings.InterfaceRequest, and
	// p is a bindings.InterfacePointer.
	r, p := bindings.CreateMessagePipeForMojoInterface()
	v := v23ServiceRequest{
		request: r,
		name:    mojoname,
	} // v is an application.ServiceRequest with mojoname

	// Connect to the mojourl.
	fs.appctx.ConnectToApplication(mojourl).ConnectToService(&v)

	// Then assign a new router the FakeService.
	// This will never conflict because each FakeService is only invoked once.
	fs.router = bindings.NewRouter(p.PassMessagePipe(), bindings.GetAsyncWaiter())
	defer fs.Close_Proxy()

	log.Printf("Fake Service Invoke (Remote Signature)")

	// Vanadium relies on type information, so we will retrieve that first.
	mojomInterface, desc, err := fs.callRemoteSignature(mojourl, mojoname)
	if err != nil {
		return nil, err
	}

	log.Printf("Fake Service Invoke Signature %v", mojomInterface)
	log.Printf("Fake Service Invoke (Remote Method)")

	// With the type information, we can make the method call to the remote interface.
	methodResults, err := fs.callRemoteMethod(method, mojomInterface, desc, argptrs)
	if err != nil {
		return nil, err
	}

	log.Printf("Fake Service Invoke Results %v", methodResults)

	// Convert methodResult to results.
	results = make([]interface{}, len(methodResults))
	for i := range methodResults {
		results[i] = &methodResults[i]
	}
	return results, nil
}

func (fs fakeService) Close_Proxy() {
	fs.router.Close()
}

// callRemoteSignature obtains type and header information from the remote
// mojo service. Remote mojo interfaces all define a signature method.
func (fs fakeService) callRemoteSignature(mojourl string, mojoname string) (mojomInterface mojom_types.MojomInterface, desc map[string]mojom_types.UserDefinedType, err error) {
	/*log.Printf("callRemoteSignature: Prepare payload and header")

	// Prepare the input for the mojo call.
	// This consists of a payload and a header for the RemoteSignature.
	payload := mojom_types.SignatureInput{}
	header := bindings.MessageHeader{
		Type:      0xffffffff,                          // Signature is always type 0xffffffff
		Flags:     bindings.MessageExpectsResponseFlag, // It always has a response.
		RequestId: fs.ids.Count(),
	}

	log.Printf("callRemoteSignature: Encode payload and header")

	var message *bindings.Message
	if message, err = bindings.EncodeMessage(header, &payload); err != nil {
		return response, fmt.Errorf("can't encode request: %v", err.Error())
	}

	log.Printf("callRemoteSignature => callRemoteGeneric")

	outMessage, err := fs.callRemoteGeneric(message)
	if err != nil {
		return response, err
	}

	log.Printf("callRemoteSignature: Decode response")

	if err = outMessage.DecodePayload(&response); err != nil {
		return
	}

	return response, nil*/

	// TODO(afandria): The service_describer mojom file defines the constant, but
	// it is not actually present in the generated code:
	// https://github.com/domokit/mojo/issues/469
	// serviceDescriberInterfaceName := "_ServiceDescriber"

	r, p := service_describer.CreateMessagePipeForServiceDescriber()
	fs.appctx.ConnectToApplication(mojourl).ConnectToService(&r)
	sDescriber := service_describer.NewServiceDescriberProxy(p, bindings.GetAsyncWaiter())
	defer sDescriber.Close_Proxy()

	r2, p2 := service_describer.CreateMessagePipeForServiceDescription()
	err = sDescriber.DescribeService(mojoname, r2)
	if err != nil {
		return
	}
	sDescription := service_describer.NewServiceDescriptionProxy(p2, bindings.GetAsyncWaiter())
	defer sDescription.Close_Proxy()

	mojomInterface, err = sDescription.GetTopLevelInterface()
	if err != nil {
		return
	}
	descPtr, err := sDescription.GetAllTypeDefinitions()
	if err != nil {
		return
	}
	return mojomInterface, *descPtr, nil
}

// A helper function that sends a remote message that expects a response.
func (fs fakeService) callRemoteGeneric(message *bindings.Message) (outMessage *bindings.Message, err error) {
	log.Printf("callRemoteGeneric: Send message along the router")

	readResult := <-fs.router.AcceptWithResponse(message)
	if err = readResult.Error; err != nil {
		return
	}

	log.Printf("callRemoteGeneric: Audit response message header flag")
	// The message flag we receive back must be a bindings.MessageIsResponseFlag
	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
		}
		return
	}

	log.Printf("callRemoteGeneric: Audit response message header type")
	// While the mojo service we called into will return a header whose
	// type must match our outgoing one.
	if got, want := readResult.Message.Header.Type, message.Header.Type; got != want {
		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
		}
		return
	}

	return readResult.Message, nil
}

// callRemoteMethod calls the method remotely in a generic way.
// Produces []*vdl.Value at the end for the invoker to return.
func (fs fakeService) callRemoteMethod(method string, mi mojom_types.MojomInterface, desc map[string]mojom_types.UserDefinedType, argptrs []interface{}) ([]*vdl.Value, error) {
	// We need to parse the signature result to get the method relevant info out.
	found := false
	var ordinal uint32
	for ord, mm := range mi.Methods {
		if *mm.DeclData.ShortName == method {
			ordinal = ord
			found = true
			break
		}
	}

	if !found {
		return nil, fmt.Errorf("callRemoteMethod: method %s does not exist", method)
	}

	mm := mi.Methods[ordinal]

	// A void function must have request id of 0, whereas one with response params
	// should  have a unique request id.
	var rqId uint64
	var flag uint32
	if mm.ResponseParams != nil {
		rqId = fs.ids.Count()
		flag = bindings.MessageExpectsResponseFlag
	} else {
		flag = bindings.MessageNoFlag
	}

	header := bindings.MessageHeader{
		Type:      ordinal,
		Flags:     flag,
		RequestId: rqId,
	}

	// Now produce the *bindings.Message that we will send to the other side.
	inType := transcoder.MojomStructToVDLType(mm.Parameters, desc)
	message, err := encodeMessageFromVom(header, argptrs, inType)
	if err != nil {
		return nil, err
	}

	// Handle the 0 out-arg case first.
	if mm.ResponseParams == nil {
		if err = fs.router.Accept(message); err != nil {
			return nil, err
		}
		return make([]*vdl.Value, 0), nil
	}

	// Otherwise, make a generic call with the message.
	outMessage, err := fs.callRemoteGeneric(message)
	if err != nil {
		return nil, err
	}

	// Decode the *vdl.Value from the mojom bytes and mojom type.
	outType := transcoder.MojomStructToVDLType(*mm.ResponseParams, desc)
	var outVdlValue *vdl.Value
	if err := transcoder.MojomToVdl(outMessage.Payload, outType, &outVdlValue); err != nil {
		return nil, fmt.Errorf("transcoder.MojoToVom failed: %v", err)
	}

	// Then split the *vdl.Value (struct) into []*vdl.Value
	response := splitVdlValueByMojomType(outVdlValue, outType)
	return response, nil
}

// The fake service has no signature.
func (fs fakeService) Signature(ctx *context.T, call rpc.ServerCall) ([]signature.Interface, error) {
	log.Printf("Fake Service Signature???")
	return nil, nil
}

// The fake service knows nothing about method signatures.
func (fs fakeService) MethodSignature(ctx *context.T, call rpc.ServerCall, method string) (signature.Method, error) {
	log.Printf("Fake Service Method Signature???")
	return signature.Method{}, nil
}

// The fake service will never need to glob.
func (fs fakeService) Globber() *rpc.GlobState {
	log.Printf("Fake Service Globber???")
	return nil
}
