/*
 * 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), incmg:make(chan *incoming)}
	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 {
	log.Debug("Serving server streaming {{$.Name}}")
	return nil
}
{{else if .Cs}}
func (ts {{$.Name}}TestServer) {{.Name}}({{.Pkg}}.{{.Svc}}_{{.Name}}Server) error {
	log.Debug("Serving client streaming {{$.Name}}")
	return nil
}
{{else}}
func  (ts {{$.Name}}TestServer) {{.Name}}(ctx context.Context, in *{{.Param}}) (*{{.Rtrn}}, error) {
	var r * incoming = &incoming{}
	log.Debug("Serving {{$.Name}}")
	// 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
	go func(ctx context.Context) {
		select {
		case ts.control.incmg <- r:
			return
		case <-ctx.Done():
			return

		}
	}(glCtx)
	// Read the value that needs to be returned from the channel
	select {
	case 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}}")
		}
	case <-glCtx.Done():
		return nil, errors.New("Timeout: nothing in the reply data channel in call to {{.Name}}, sending nil")
	}
	return &{{.Rtrn}}{},nil
}
{{end}}
{{end}}

