/*
 * 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.
 */
// The template for the tester.
// This template is filled in by the
// test driver based on the configuration.

package main

import (
	"fmt"
	"net"
	"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
)

// The channels to get fed the expected results by the test driver.
//var {{.Name}}Meta <-chan string
////var {{.Name}}Payload <-chan string

{{if .Ct}}{{else}}
type reply struct {
	repl interface{}
}
type incoming struct {
	meta metadata.MD
	payload string
}
type  serverCtl struct {
	replyData chan * reply
	incmg chan * incoming
}
{{end}}

type {{.Name}}TestServer struct {
	control *serverCtl
	srv *grpc.Server
}

/*
func init() {
	{{if .Ct}}{{else}}
	if _, err := log.SetDefaultLogger(log.JSON, 0, nil); err != nil {
		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
	}
	{{end}}
	{{.Name}}ListenAndServe()
}
*/


func {{.Name}}ListenAndServe() error {
	var s {{.Name}}TestServer

	s.control = &serverCtl{replyData:make(chan *reply,1), incmg:make(chan *incoming,1)}
	servers["{{.Name}}"] = s.control

	log.Debugf("Starting server %s on port %d", "{{.Name}}", {{.Port}})
	// THe test head always uses localhost 127.0.0.1
	addr := fmt.Sprintf("127.0.0.1:%d", {{.Port}})

	// Create the gRPC server
	s.srv = grpc.NewServer()

{{range .ProtoImports}}
	// Register the handler object
	{{.Short}}.Register{{.Service}}Server(s.srv, s)
{{end}}

	// Create the channel to listen on
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		log.Errorf("could not listen on %s: %s", addr, err)
		return err
	}

	// Serve and Listen
	go func() {
		if err = s.srv.Serve(lis); err != nil {
			log.Errorf("grpc serve error: %s", err)
			return
		}
	}()

	return err
}

{{range .Methods}}
{{if .Ss}}
func (ts {{$.Name}}TestServer) {{.Name}}(in *{{.Param}}, srvr {{.Pkg}}.{{.Svc}}_{{.Name}}Server) error {
	return nil
}
{{else if .Cs}}
func (ts {{$.Name}}TestServer) {{.Name}}({{.Pkg}}.{{.Svc}}_{{.Name}}Server) error {
	return nil
}
{{else}}
func  (ts {{$.Name}}TestServer) {{.Name}}(ctx context.Context, in *{{.Param}}) (*{{.Rtrn}}, error) {
	var r * incoming = &incoming{}
	// Read the metadata
	if md,ok := metadata.FromIncomingContext(ctx); ok == false {
		log.Error("Getting matadata during call to {{.Name}}")
	} else {
		r.meta = md.Copy()
	}
	// Read the data sent to the function
	if parm,err := json.Marshal(in); err != nil {
		log.Error("Marshalling the {{.Param}} for {{.Name}}")
	} else {
		r.payload = string(parm)
	}
	// Send the server information back to the test framework
	ts.control.incmg <- r
	// Read the value that needs to be returned from the channel
	d := <-ts.control.replyData
	switch r := d.repl.(type) {
		case *{{.Rtrn}}:
			return r, nil
		default:
			return nil, errors.New("Mismatched type in call to {{.Name}}")
	}
	return &{{.Rtrn}}{},nil
}
{{end}}
{{end}}

