// 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 main

import (
	"fmt"
	"log"
	"strings"

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

	v23 "v.io/x/mojo/client"

	"mojom/examples/echo"
	"mojom/vanadium/discovery"
)

//#include "mojo/public/c/system/types.h"
import "C"

type handler struct {
	ch chan string
}

func (h *handler) Found(s discovery.Service) error {
	log.Println("found ", s)
	h.ch <- s.Addrs[0]
	return nil
}

func (h *handler) Lost(s string) error {
	log.Println("Lost ", s)
	return nil
}

type RemoteEchoClientDelegate struct {
}

func (delegate *RemoteEchoClientDelegate) findService(ctx application.Context) (string, error) {
	r, p := discovery.CreateMessagePipeForScanner()
	ctx.ConnectToApplication("https://mojo.v.io/scanner.mojO").ConnectToService(&r)
	scanner := discovery.NewScannerProxy(p, bindings.GetAsyncWaiter())
	scanReq, scanPtr := discovery.CreateMessagePipeForScanHandler()
	ch := make(chan string)
	stub := discovery.NewScanHandlerStub(scanReq, &handler{ch: ch}, bindings.GetAsyncWaiter())
	id, e1, e2 := scanner.Scan(`v.InterfaceName="mojo.examples.echo.RemoteEcho"`, scanPtr)
	if e1 != nil {
		return "", fmt.Errorf("%s", e1.Msg)
	}

	if e2 != nil {
		return "", e2
	}
	go func() {
		err := stub.ServeRequest()
		if err != nil {
			log.Println("failed to get result", err)
			ch <- ""
		}
		scanner.Stop(id)
		stub.Close()
	}()
	res := <-ch
	return res, nil
}

// When running echo_client, ctx.Args() should contain:
// 0: mojo app name
// 1: remote endpoint
// 2+: string to echo
func (delegate *RemoteEchoClientDelegate) Initialize(ctx application.Context) {
	log.Printf("RemoteEchoClientDelegate.Initialize...")

	remoteEndpoint, err := delegate.findService(ctx)
	if err != nil {
		log.Println("Failed to start get address:", err)
		return
	}

	// Parse arguments. Note: May panic if not enough args are given.
	echoString := "Hello, Go world!"
	if len(ctx.Args()) > 1 {
		echoString = strings.Join(ctx.Args()[1:], " ")
	}

	r, p := echo.CreateMessagePipeForRemoteEcho()

	v23.ConnectToRemoteService(ctx, &r, remoteEndpoint)
	echoProxy := echo.NewRemoteEchoProxy(p, bindings.GetAsyncWaiter())

	log.Printf("RemoteEchoClientDelegate.Initialize calling EchoString...")
	response, err := echoProxy.EchoString(echoString)
	if err == nil {
		fmt.Printf("client: %s\n", response)
	} else {
		log.Println(err)
	}

	log.Printf("RemoteEchoClientDelegate.Initialize calling EchoX...")
	response2, err := echoProxy.EchoX([]bool{true, false, false, true}, echo.AInArg{"A String"})
	if err == nil {
		fmt.Printf("client: %v\n", response2)
	} else {
		log.Println("Error: ", err)
	}

	fmt.Printf("(done)\n")
	echoProxy.Close_Proxy()
	ctx.Close()
}

func (delegate *RemoteEchoClientDelegate) AcceptConnection(connection *application.Connection) {
	log.Printf("RemoteEchoClientDelegate.AcceptConnection...")
	connection.Close()
}

func (delegate *RemoteEchoClientDelegate) Quit() {
	log.Printf("RemoteEchoClientDelegate.Quit...")
}

//export MojoMain
func MojoMain(handle C.MojoHandle) C.MojoResult {
	application.Run(&RemoteEchoClientDelegate{}, system.MojoHandle(handle))
	return C.MOJO_RESULT_OK
}

func main() {
}
