/*
 * Copyright 2018-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package main

import (
	"fmt"
	"errors"
	"encoding/json"
	"google.golang.org/grpc"
	"golang.org/x/net/context"
	"google.golang.org/grpc/metadata"
	"github.com/opencord/voltha-go/common/log"
	// Values generated by the go template
	{{range .Imports}}
	"{{.}}"
	{{end}}
	{{range .ProtoImports}}
	{{.Short}} "{{.Package}}"
	{{end}}
	// End go template values
)

{{if .Ct}}{{else}}
type clientCtl struct {
	send func(string, context.Context, interface{}, string, metadata.MD) error
	cncl  context.CancelFunc
	ctx context.Context
}
{{end}}

type {{.Name}}ClientConn struct {
	conn * grpc.ClientConn
	control * clientCtl
}


var {{.Name}}Client *{{.Name}}ClientConn


func {{.Name}}Connect() (*{{.Name}}ClientConn, error)  {
	log.Infof("Connecting client {{.Name}} to addr:127.0.0.1, port:{{.Port}}")
	// Dial doesn't block, it just returns and continues connecting in the background.
	// Check back later to confirm and increase the connection count.
	cl := &{{.Name}}ClientConn{control:&clientCtl{}}
	ctx, cnclFnc := context.WithCancel(context.Background())
	cl.control.cncl = cnclFnc
	cl.control.ctx = ctx
	if conn, err := grpc.Dial("127.0.0.1:{{.Port}}", grpc.WithInsecure()); err != nil {
		log.Errorf("Dialng connection :%v",err)
		return nil, err
	} else {
		cl.conn = conn
	}
	{{.Name}}Client = cl
	cl.control.send = {{.Name}}Send
	clients["{{.Name}}"] = cl.control
	return cl, nil
}

// This function will make the requested RPC with the supplied
// parameter and validate that the response matches the expected
// value provided. It will return nil if successful or an error
// if not.
func {{.Name}}Send(mthd string, ctx context.Context, param interface{},
					expect string, expectMeta metadata.MD) error {
	switch mthd {
	{{range .Methods}}
	case "{{.Name}}":
		var hdr metadata.MD
		switch t := param.(type) {
		case *{{.Param}}:
	{{if .Ss}}
			_=t
			_=hdr
	{{else if .Cs}}
			_=t
			_=hdr
	{{else}}
			client := {{.Pkg}}.New{{.Svc}}Client({{$.Name}}Client.conn)
			res, err := client.{{.Name}}(ctx, t, grpc.Header(&hdr))
			if err != nil {
				return errors.New("Error sending method {{.Name}}")
			}
			// Marshal the result and compare it to the expected
			// value.
			if resS,err := json.Marshal(res); err == nil {
				if string(resS) != expect {
					stats.testLog("Unexpected result returned expected '%s' got '%s'\n", expect, string(resS))
					return errors.New("Unexpected result on method {{.Name}}")
				}
			} else {
				return errors.New("Error Marshaling the reply for method {{.Name}}")
			}
			// Now validate the metadata in the response
			for k,v := range expectMeta {
				if rv,ok := hdr[k]; ok == true {
					if rv[0] != v[0] {
						stats.testLog("Mismatch on returned metadata for key '%s' expected '%s' and got '%s'\n", k, v, rv)
						err = errors.New("Failure on returned metadata")
					}
				} else {
					stats.testLog("Returned metadata missing key '%s'; expected value '%s' at that key\n", k, v)
					err = errors.New("Failure on returned metadata")
				}
			}
			return err
		default:
			return errors.New("Invalid parameter type for method {{.Name}}")
	{{end}}
		}
	{{end}}
		default:
			return errors.New(fmt.Sprintf("Unexpected method %s in send", mthd))
	}
	return nil
}

