// +build integration

/*
 * 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.
 */
// gRPC affinity router with active/active backends

package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"github.com/golang/protobuf/proto"
	pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/opencord/voltha-lib-go/v2/pkg/log"
	"io/ioutil"
	"math"
	"os"
	"os/exec"
	"path"
	"regexp"
	"strconv"
	"text/template"
)

const MAX_CT = 500

type TestConfig struct {
	configFile *string
	logLevel   *int
	grpcLog    *bool
	Suites     []string `json:"suites"`
}

type Connection struct {
	Name string `json:"name"`
	Port string `json:"port"`
}

type EndpointList struct {
	Imports   []string     `json:"imports"`
	Endpoints []Connection `json:"endPoints"`
}

type ProtoFile struct {
	ImportPath string `json:"importPath"`
	Service    string `json:"service"`
	Package    string `json:"package"`
}

type ProtoSubst struct {
	From string `json:"from"`
	To   string `json:"to"`
}

type Environment struct {
	Command     string       `json:"cmdLine"`
	ProtoFiles  []ProtoFile  `json:"protoFiles"`
	ProtoDesc   string       `json:"protoDesc"`
	Clients     EndpointList `json:"clients"`
	Servers     EndpointList `json:"servers"`
	Imports     []string     `json:"imports"`
	ProtoSubsts []ProtoSubst `json:"protoSubst"`
}

type Rpc struct {
	Client     string  `json:"client"`
	Method     string  `json:"method"`
	Param      string  `json:"param"`
	Expect     string  `json:"expect"`
	MetaData   []MetaD `json:"meta"`
	ExpectMeta []MetaD `json:"expectMeta"`
}

type MetaD struct {
	Key string `json:"key"`
	Val string `json:"value"`
}

type Server struct {
	Name string  `json:"name"`
	Meta []MetaD `json:"meta"`
}

type Test struct {
	Name     string   `json:"name"`
	InfoOnly bool     `json:"infoOnly"`
	Send     Rpc      `json:"send"`
	Servers  []Server `json:"servers"`
}

type TestSuite struct {
	Env   Environment `json:"environment"`
	Tests []Test      `json:"tests"`
}

type ProtoImport struct {
	Service string
	Short   string
	Package string
	Used    bool
}

type SendItem struct {
	Client     string
	Method     string
	Param      string
	ParamType  string
	Expect     string
	ExpectType string
	MetaData   []MetaD
	ExpectMeta []MetaD
}

type TestCase struct {
	Name     string
	InfoOnly bool
	Send     SendItem
	Srvr     []Server
}

type MethodTypes struct {
	ParamType     string
	ReturnType    string
	CodeGenerated bool
}

type Import struct {
	Package string
	Used    bool
}

type TestList struct {
	ProtoImports     []ProtoImport
	Imports          []Import
	Tests            []TestCase
	Funcs            map[string]MethodTypes
	RunTestsCallList []string
	FileNum          int
	//NextFile int
	HasFuncs bool
	Offset   int
}

type ClientConfig struct {
	Ct           int
	Name         string
	Port         string
	Imports      []string
	Methods      map[string]*mthd
	ProtoImports []ProtoImport
}

type ServerConfig struct {
	Ct           int
	Name         string
	Port         string
	Imports      []string
	Methods      map[string]*mthd
	ProtoImports []ProtoImport
}

type mthd struct {
	Pkg   string
	Svc   string
	Name  string
	Param string
	Rtrn  string
	Ss    bool // Server streaming
	Cs    bool // Clieent streaming
}

func parseCmd() (*TestConfig, error) {
	config := &TestConfig{}
	cmdParse := flag.NewFlagSet(path.Base(os.Args[0]), flag.ContinueOnError)
	config.configFile = cmdParse.String("config", "suites.json", "The configuration file for the affinity router tester")
	config.logLevel = cmdParse.Int("logLevel", 0, "The log level for the affinity router tester")
	config.grpcLog = cmdParse.Bool("grpclog", false, "Enable GRPC logging")

	err := cmdParse.Parse(os.Args[1:])
	if err != nil {
		//return err
		return nil, errors.New("Error parsing the command line")
	}
	return config, nil
}

func (conf *TestConfig) loadConfig() error {

	configF, err := os.Open(*conf.configFile)
	log.Info("Loading configuration from: ", *conf.configFile)
	if err != nil {
		log.Error(err)
		return err
	}

	defer configF.Close()

	if configBytes, err := ioutil.ReadAll(configF); err != nil {
		log.Error(err)
		return err
	} else if err := json.Unmarshal(configBytes, conf); err != nil {
		log.Error(err)
		return err
	}

	return nil
}

func (suite *TestSuite) loadSuite(suiteN string) error {
	// Check if there's a corresponding go file for the suite.
	// If it is present then the json test suite file is a
	// template. Compile the go file and run it to process
	// the template.
	if _, err := os.Stat(suiteN + "/" + suiteN + ".go"); err == nil {
		// Compile and run the the go file
		log.Infof("Suite '%s' is a template, compiling '%s'", suiteN, suiteN+".go")
		cmd := exec.Command("go", "build", "-o", suiteN+".te", suiteN+".go")
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = suiteN
		if err := cmd.Run(); err != nil {
			log.Errorf("Error running the compile command:%v", err)
		}
		cmd = exec.Command("./" + suiteN + ".te")
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		cmd.Dir = suiteN
		if err := cmd.Run(); err != nil {
			log.Errorf("Error running the %s command:%v", suiteN+".te", err)
		}
	}
	suiteF, err := os.Open(suiteN + "/" + suiteN + ".json")
	log.Infof("Loading test suite from: %s", suiteN+"/"+suiteN+".json")
	if err != nil {
		log.Error(err)
		return err
	}

	defer suiteF.Close()

	if suiteBytes, err := ioutil.ReadAll(suiteF); err != nil {
		log.Error(err)
		return err
	} else if err := json.Unmarshal(suiteBytes, suite); err != nil {
		log.Error(err)
		return err
	}

	return nil
}

func loadProtoMap(fileName string, pkg string, svc string, substs []ProtoSubst) (map[string]*mthd, error) {
	var mthds map[string]*mthd = make(map[string]*mthd)
	var rtrn_err bool

	// Load the protobuf descriptor file
	protoDescriptor := &pb.FileDescriptorSet{}
	fb, err := ioutil.ReadFile(fileName)
	if err != nil {
		log.Errorf("Could not open proto file '%s'", fileName)
		rtrn_err = true
	}
	err = proto.Unmarshal(fb, protoDescriptor)
	if err != nil {
		log.Errorf("Could not unmarshal %s, %v", "proto.pb", err)
		rtrn_err = true
	}

	var substM map[string]string = make(map[string]string)
	// Create a substitution map
	log.Debugf("Creating import map")
	for _, v := range substs {
		log.Debugf("Mapping from %s to %s", v.From, v.To)
		substM[v.From] = v.To
	}

	// Build the a map containing the method as the key
	// and the paramter and return types as the fields
	for _, f := range protoDescriptor.File {
		if *f.Package == pkg {
			for _, s := range f.Service {
				if *s.Name == svc {
					log.Debugf("Loading package data '%s' for service '%s'", *f.Package, *s.Name)
					// Now create a map keyed by method name with the value being the
					// field number of the route selector.
					//var ok bool
					for _, m := range s.Method {
						// Find the input type in the messages and extract the
						// field number and save it for future reference.
						log.Debugf("Processing method (%s(%s) (%s){}", *m.Name, (*m.InputType)[1:], (*m.OutputType)[1:])
						mthds[*m.Name] = &mthd{Pkg: pkg, Svc: svc, Name: *m.Name, Param: (*m.InputType)[1:],
							Rtrn: (*m.OutputType)[1:]}
						if m.ClientStreaming != nil && *m.ClientStreaming == true {
							log.Debugf("Method %s is a client streaming method", *m.Name)
							mthds[*m.Name].Cs = true
						}
						if m.ServerStreaming != nil && *m.ServerStreaming == true {
							log.Debugf("Method %s is a server streaming method", *m.Name)
							mthds[*m.Name].Ss = true
						}
						// Perform the required substitutions
						if _, ok := substM[mthds[*m.Name].Param]; ok == true {
							mthds[*m.Name].Param = substM[mthds[*m.Name].Param]
						}
						if _, ok := substM[mthds[*m.Name].Rtrn]; ok == true {
							mthds[*m.Name].Rtrn = substM[mthds[*m.Name].Rtrn]
						}
					}
				}
			}
		}
	}
	if rtrn_err {
		return nil, errors.New(fmt.Sprintf("Failed to load protobuf descriptor file '%s'", fileName))
	}
	return mthds, nil
}

// Server source code generation
func generateServers(conf *TestConfig, suiteDir string, ts *TestSuite,
	t *template.Template) error {
	var servers []ServerConfig

	for k, v := range ts.Env.Servers.Endpoints {
		log.Infof("Generating the code for server[%d]: %s", k, v.Name)
		sc := &ServerConfig{Name: v.Name, Port: v.Port, Ct: k, Imports: ts.Env.Servers.Imports,
			Methods: make(map[string]*mthd)}
		for k1, v1 := range ts.Env.ProtoFiles {
			imp := &ProtoImport{Short: "pb" + strconv.Itoa(k1),
				Package: v1.ImportPath + v1.Package,
				Service: v1.Service,
				Used:    true}
			imp = &ProtoImport{Short: v1.Package,
				Package: v1.ImportPath + v1.Package,
				Service: v1.Service,
				Used:    true}
			sc.ProtoImports = append(sc.ProtoImports, *imp)
			// Compile the template from the file
			log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
			if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v1.Package,
				v1.Service, ts.Env.ProtoSubsts); err != nil {
				log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
					ts.Env.ProtoDesc, v1.Package, v1.Service)
				return err
			} else {
				//Generate all the function calls required by the
				for k, v := range mthds {
					sc.Methods[k] = v
				}
				//sc.Methods = mthds
			}
		}
		log.Debugf("Server: %v", *sc)
		// Save this server for the next steop
		servers = append(servers, *sc)
		// Open an output file to put the output in.
		if f, err := os.Create(suiteDir + "/" + v.Name + ".go"); err == nil {
			defer f.Close()
			//if err := t.ExecuteTemplate(os.Stdout, "server.go.tmpl", *sc); err != nil {}
			if err := t.ExecuteTemplate(f, "server.go.tmpl", *sc); err != nil {
				log.Errorf("Unable to execute template for server[%d]: %s: %v", k, v.Name, err)
				return err
			}
		}
	}
	// Generate the server initialization code
	if f, err := os.Create(suiteDir + "/serverInit.go"); err == nil {
		defer f.Close()
		//if err := t.ExecuteTemplate(os.Stdout, "server.go.tmpl", *sc); err != nil {}
		if err := t.ExecuteTemplate(f, "serverInit.go.tmpl", servers); err != nil {
			log.Errorf("Unable to execute template for serverInit.go: %v", err)
			return err
		}
	}

	return nil
}

func generateClients(conf *TestConfig, suiteDir string, ts *TestSuite,
	t *template.Template) error {
	var clients []ClientConfig
	for k, v := range ts.Env.Clients.Endpoints {
		log.Infof("Generating the code for client[%d]: %s", k, v.Name)
		cc := &ClientConfig{Name: v.Name, Port: v.Port, Ct: k, Imports: ts.Env.Clients.Imports,
			Methods: make(map[string]*mthd)}
		for _, v1 := range ts.Env.ProtoFiles {
			imp := &ProtoImport{Short: v1.Package,
				Package: v1.ImportPath + v1.Package,
				Service: v1.Service}
			cc.ProtoImports = append(cc.ProtoImports, *imp)
			// Compile the template from the file
			log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
			if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v1.Package,
				v1.Service, ts.Env.ProtoSubsts); err != nil {
				log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
					ts.Env.ProtoDesc, v1.Package, v1.Service)
				return err
			} else {
				// Add to the known methods
				for k, v := range mthds {
					cc.Methods[k] = v
				}
			}
		}
		clients = append(clients, *cc)
		if f, err := os.Create(suiteDir + "/" + v.Name + "_client.go"); err == nil {
			_ = f
			defer f.Close()
			if err := t.ExecuteTemplate(f, "client.go.tmpl", cc); err != nil {
				log.Errorf("Unable to execute template for client.go: %v", err)
				return err
			}
		} else {
			log.Errorf("Couldn't create file %s : %v", suiteDir+"/"+v.Name+"_client.go", err)
			return err
		}
	}
	if f, err := os.Create(suiteDir + "/clientInit.go"); err == nil {
		defer f.Close()
		//if err := t.ExecuteTemplate(os.Stdout, "server.go.tmpl", *sc); err != nil {}
		if err := t.ExecuteTemplate(f, "clientInit.go.tmpl", clients); err != nil {
			log.Errorf("Unable to execute template for clientInit.go: %v", err)
			return err
		}
	}
	return nil
}

func serverExists(srvr string, ts *TestSuite) bool {
	for _, v := range ts.Env.Servers.Endpoints {
		if v.Name == srvr {
			return true
		}
	}
	return false
}

func getPackageList(tests []TestCase) map[string]struct{} {
	var rtrn map[string]struct{} = make(map[string]struct{})
	var p string
	var e string
	r := regexp.MustCompile(`^([^.]+)\..*$`)
	for _, v := range tests {
		pa := r.FindStringSubmatch(v.Send.ParamType)
		if len(pa) == 2 {
			p = pa[1]
		} else {
			log.Errorf("Internal error regexp returned %v", pa)
		}
		ea := r.FindStringSubmatch(v.Send.ExpectType)
		if len(ea) == 2 {
			e = ea[1]
		} else {
			log.Errorf("Internal error regexp returned %v", pa)
		}
		if _, ok := rtrn[p]; ok == false {
			rtrn[p] = struct{}{}
		}
		if _, ok := rtrn[e]; ok == false {
			rtrn[e] = struct{}{}
		}
	}
	return rtrn
}

func fixupProtoImports(protoImports []ProtoImport, used map[string]struct{}) []ProtoImport {
	var rtrn []ProtoImport
	//log.Infof("Updating imports %v, using %v", protoImports, used)
	for _, v := range protoImports {
		//log.Infof("Looking for package %s", v.Package)
		if _, ok := used[v.Short]; ok == true {
			rtrn = append(rtrn, ProtoImport{
				Service: v.Service,
				Short:   v.Short,
				Package: v.Package,
				Used:    true,
			})
		} else {
			rtrn = append(rtrn, ProtoImport{
				Service: v.Service,
				Short:   v.Short,
				Package: v.Package,
				Used:    false,
			})
		}
	}
	//log.Infof("After update %v", rtrn)
	return rtrn
}

func fixupImports(imports []Import, used map[string]struct{}) []Import {
	var rtrn []Import
	var p string
	re := regexp.MustCompile(`^.*/([^/]+)$`)
	//log.Infof("Updating imports %v, using %v", protoImports, used)
	for _, v := range imports {
		//log.Infof("Looking for match in %s", v.Package)
		pa := re.FindStringSubmatch(v.Package)
		if len(pa) == 2 {
			p = pa[1]
		} else {
			log.Errorf("Substring match failed, regexp returned %v", pa)
		}
		//log.Infof("Looking for package %s", v.Package)
		if _, ok := used[p]; ok == true {
			rtrn = append(rtrn, Import{
				Package: v.Package,
				Used:    true,
			})
		} else {
			rtrn = append(rtrn, Import{
				Package: v.Package,
				Used:    false,
			})
		}
	}
	//log.Infof("After update %v", rtrn)
	return rtrn
}

func generateTestCases(conf *TestConfig, suiteDir string, ts *TestSuite,
	t *template.Template) error {
	var mthdMap map[string]*mthd
	mthdMap = make(map[string]*mthd)
	// Generate the test cases
	log.Info("Generating the test cases: runTests.go")
	tc := &TestList{Funcs: make(map[string]MethodTypes),
		FileNum: 0, HasFuncs: false,
		Offset: 0}
	for _, v := range ts.Env.Imports {
		tc.Imports = append(tc.Imports, Import{Package: v, Used: true})
	}

	// Load the proto descriptor file
	for _, v := range ts.Env.ProtoFiles {
		imp := &ProtoImport{Short: v.Package,
			Package: v.ImportPath + v.Package,
			Service: v.Service,
			Used:    true}
		tc.ProtoImports = append(tc.ProtoImports, *imp)
		// Compile the template from the file
		log.Debugf("Proto substs: %v", ts.Env.ProtoSubsts)
		if mthds, err := loadProtoMap(ts.Env.ProtoDesc, v.Package,
			v.Service, ts.Env.ProtoSubsts); err != nil {
			log.Errorf("Unable to process proto descriptor file %s for package: %s, service: %s",
				ts.Env.ProtoDesc, v.Package, v.Service)
			return err
		} else {
			// Add to the known methods
			for k, v := range mthds {
				mthdMap[k] = v
			}
		}
	}
	// Since the input file can possibly be a template with loops that
	// make multiple calls to exactly the same method with potentially
	// different parameters it is best to try to optimize for that case.
	// Creating a function for each method used will greatly reduce the
	// code size and repetition. In the case where a method is used only
	// once the resulting code will be bigger but this is an acceptable
	// tradeoff to allow huge suites that call the same method repeatedly
	// to test for leaks.

	// The go compiler has trouble compiling files that are too large. In order
	// to mitigate that, It's necessary to create more smaller files than the
	// single one large one while making sure that the functions for the distinct
	// methods are only defined once in one of the files.

	// Yet another hiccup with the go compiler, it doesn't like deep function
	// nesting meaning that each runTests function can't call the next without
	// eventually blowing the stack check. In order to work around this, the
	// first runTests function needs to call all the others in sequence to
	// keep the stack depth constant.

	// Counter limiting the number of tests to output to each file
	maxCt := MAX_CT

	// Get the list of distinct methods
	//for _,v := range ts.Tests {
	//	if _,ok := tc.Funcs[v.Send.Method]; ok == false {
	//		tc.Funcs[v.Send.Method] = MethodTypes{ParamType:mthdMap[v.Send.Method].Param,
	//											  ReturnType:mthdMap[v.Send.Method].Rtrn}
	//	}
	//}
	for i := 1; i < int(math.Ceil(float64(len(ts.Tests))/float64(MAX_CT))); i++ {
		tc.RunTestsCallList = append(tc.RunTestsCallList, "runTests"+strconv.Itoa(i))
	}

	// Create the test data structure for the template
	for _, v := range ts.Tests {
		var test TestCase

		if _, ok := tc.Funcs[v.Send.Method]; ok == false {
			tc.Funcs[v.Send.Method] = MethodTypes{ParamType: mthdMap[v.Send.Method].Param,
				ReturnType:    mthdMap[v.Send.Method].Rtrn,
				CodeGenerated: false}
			tc.HasFuncs = true
		}

		test.Name = v.Name
		test.InfoOnly = v.InfoOnly
		test.Send.Client = v.Send.Client
		test.Send.Method = v.Send.Method
		test.Send.Param = v.Send.Param
		test.Send.ParamType = mthdMap[test.Send.Method].Param
		test.Send.Expect = v.Send.Expect
		test.Send.ExpectType = mthdMap[test.Send.Method].Rtrn
		for _, v1 := range v.Send.MetaData {
			test.Send.MetaData = append(test.Send.MetaData, v1)
		}
		for _, v1 := range v.Send.ExpectMeta {
			test.Send.ExpectMeta = append(test.Send.ExpectMeta, v1)
		}
		for _, v1 := range v.Servers {
			var srvr Server
			if serverExists(v1.Name, ts) == false {
				log.Errorf("Server '%s' is not defined!!", v1.Name)
				return errors.New(fmt.Sprintf("Failed to build test case %s", v.Name))
			}
			srvr.Name = v1.Name
			srvr.Meta = v1.Meta
			test.Srvr = append(test.Srvr, srvr)
		}
		tc.Tests = append(tc.Tests, test)
		if maxCt--; maxCt == 0 {
			// Get the list of proto pacakges required for this file
			pkgs := getPackageList(tc.Tests)
			// Adjust the proto import data accordingly
			tc.ProtoImports = fixupProtoImports(tc.ProtoImports, pkgs)
			tc.Imports = fixupImports(tc.Imports, pkgs)
			//log.Infof("The packages needed are: %v", pkgs)
			if f, err := os.Create(suiteDir + "/runTests" + strconv.Itoa(tc.FileNum) + ".go"); err == nil {
				if err := t.ExecuteTemplate(f, "runTests.go.tmpl", tc); err != nil {
					log.Errorf("Unable to execute template for runTests.go: %v", err)
				}
				f.Close()
			} else {
				log.Errorf("Couldn't create file %s : %v",
					suiteDir+"/runTests"+strconv.Itoa(tc.FileNum)+".go", err)
			}
			tc.FileNum++
			//tc.NextFile++
			maxCt = MAX_CT
			// Mark the functions as generated.
			tc.Tests = []TestCase{}
			for k, v := range tc.Funcs {
				tc.Funcs[k] = MethodTypes{ParamType: v.ParamType,
					ReturnType:    v.ReturnType,
					CodeGenerated: true}
			}
			tc.HasFuncs = false
			tc.Offset += MAX_CT
			//tmp,_ := strconv.Atoi(tc.Offset)
			//tc.Offset = strconv.Itoa(tmp+500)
		}
	}
	//tc.NextFile = 0
	// Get the list of proto pacakges required for this file
	pkgs := getPackageList(tc.Tests)
	// Adjust the proto import data accordingly
	tc.ProtoImports = fixupProtoImports(tc.ProtoImports, pkgs)
	tc.Imports = fixupImports(tc.Imports, pkgs)
	//log.Infof("The packages needed are: %v", pkgs)
	if f, err := os.Create(suiteDir + "/runTests" + strconv.Itoa(tc.FileNum) + ".go"); err == nil {
		if err := t.ExecuteTemplate(f, "runTests.go.tmpl", tc); err != nil {
			log.Errorf("Unable to execute template for runTests.go: %v", err)
		}
		f.Close()
	} else {
		log.Errorf("Couldn't create file %s : %v",
			suiteDir+"/runTests"+strconv.Itoa(tc.FileNum)+".go", err)
	}

	//if f,err := os.Create(suiteDir+"/runTests.go"); err == nil {
	//	if err := t.ExecuteTemplate(f, "runTests.go.tmpl", tc); err != nil {
	//			log.Errorf("Unable to execute template for runTests.go: %v", err)
	//	}
	//	f.Close()
	//} else {
	//	log.Errorf("Couldn't create file %s : %v", suiteDir+"/runTests.go", err)
	//}
	return nil
}

func generateTestSuites(conf *TestConfig, srcDir string, outDir string) error {

	// Create a directory for the tests
	if err := os.Mkdir(srcDir, 0777); err != nil {
		log.Errorf("Unable to create directory 'tests':%v\n", err)
		return err
	}

	for k, v := range conf.Suites {
		var suiteDir string = srcDir + "/" + v
		log.Debugf("Suite[%d] - %s", k, v)
		ts := &TestSuite{}
		ts.loadSuite(v)
		log.Debugf("Suite %s: %v", v, ts)
		log.Infof("Processing test suite %s", v)

		t := template.Must(template.New("").ParseFiles("../templates/server.go.tmpl",
			"../templates/serverInit.go.tmpl",
			"../templates/client.go.tmpl",
			"../templates/clientInit.go.tmpl",
			"../templates/runTests.go.tmpl",
			"../templates/stats.go.tmpl",
			"../templates/main.go.tmpl"))
		// Create a directory for he source code for this test suite
		if err := os.Mkdir(suiteDir, 0777); err != nil {
			log.Errorf("Unable to create directory '%s':%v\n", v, err)
			return err
		}
		// Generate the server source files
		if err := generateServers(conf, suiteDir, ts, t); err != nil {
			log.Errorf("Unable to generate server source files: %v", err)
			return err
		}
		// Generate the client source files
		if err := generateClients(conf, suiteDir, ts, t); err != nil {
			log.Errorf("Unable to generate client source files: %v", err)
			return err
		}
		// Generate the test case source file
		if err := generateTestCases(conf, suiteDir, ts, t); err != nil {
			log.Errorf("Unable to generate test case source file: %v", err)
			return err
		}

		// Finally generate the main file
		log.Info("Generating main.go")
		if f, err := os.Create(suiteDir + "/main.go"); err == nil {
			if err := t.ExecuteTemplate(f, "main.go.tmpl", ts.Env); err != nil {
				log.Errorf("Unable to execute template for main.go: %v", err)
			}
			f.Close()
		} else {
			log.Errorf("Couldn't create file %s : %v", suiteDir+"/main.go", err)
		}

		log.Infof("Copying over common modules")
		if f, err := os.Create(suiteDir + "/stats.go"); err == nil {
			if err := t.ExecuteTemplate(f, "stats.go.tmpl", ts.Env); err != nil {
				log.Errorf("Unable to execute template for stats.go: %v", err)
			}
			f.Close()
		} else {
			log.Errorf("Couldn't create file %s : %v", suiteDir+"/stats.go", err)
		}

		log.Infof("Compiling test suite: %s in directory %s", v, suiteDir)
		if err := os.Chdir(suiteDir); err != nil {
			log.Errorf("Could not change to directory '%s':%v", suiteDir, err)
		}
		cmd := exec.Command("go", "build", "-o", outDir+"/"+v+".e")
		cmd.Stdin = os.Stdin
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			log.Errorf("Error running the compile command:%v", err)
		}
		if err := os.Chdir("../../suites"); err != nil {
			log.Errorf("Could not change to directory '%s':%v", "../../suites", err)
		}
	}
	return nil

}

func generateTestDriver(conf *TestConfig, srcDir string, outDir string) error {
	// Generate the main test driver file
	if err := os.Mkdir(srcDir, 0777); err != nil {
		log.Errorf("Unable to create directory 'driver':%v\n", err)
		return err
	}
	t := template.Must(template.New("").ParseFiles("../templates/runAll.go.tmpl",
		"../templates/stats.go.tmpl"))
	if f, err := os.Create(srcDir + "/runAll.go"); err == nil {
		if err := t.ExecuteTemplate(f, "runAll.go.tmpl", conf.Suites); err != nil {
			log.Errorf("Unable to execute template for runAll.go: %v", err)
		}
		f.Close()
	} else {
		log.Errorf("Couldn't create file %s : %v", srcDir+"/runAll.go", err)
	}
	if f, err := os.Create(srcDir + "/stats.go"); err == nil {
		if err := t.ExecuteTemplate(f, "stats.go.tmpl", conf.Suites); err != nil {
			log.Errorf("Unable to execute template for stats.go: %v", err)
		}
		f.Close()
	} else {
		log.Errorf("Couldn't create file %s : %v", srcDir+"/stats.go", err)
	}

	// Compile the test driver file
	log.Info("Compiling the test driver")
	if err := os.Chdir("../tests/driver"); err != nil {
		log.Errorf("Could not change to directory 'driver':%v", err)
	}
	cmd := exec.Command("go", "build", "-o", outDir+"/runAll")
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		log.Errorf("Error running the compile command:%v", err)
	}
	if err := os.Chdir("../../suites"); err != nil {
		log.Errorf("Could not change to directory 'driver':%v", err)
	}

	return nil
}

func main() {

	conf, err := parseCmd()
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	// Setup logging
	if _, err := log.SetDefaultLogger(log.JSON, *conf.logLevel, nil); err != nil {
		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
	}

	defer log.CleanUp()

	// Parse the config file
	if err := conf.loadConfig(); err != nil {
		log.Error(err)
	}

	generateTestSuites(conf, "../tests", "/src/tests")
	generateTestDriver(conf, "../tests/driver", "/src/tests")
	return
}
