/*
 * 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 (
	"os"
	"fmt"
	"flag"
	"path"
	"math"
	//"bufio"
	"errors"
	"regexp"
	"os/exec"
	"strconv"
	"io/ioutil"
	"encoding/json"
	"text/template"
	"github.com/golang/protobuf/proto"
	"github.com/opencord/voltha-go/common/log"
	pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
)

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+".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
		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
		if err := cmd.Run(); err != nil {
			log.Errorf("Error running the %s command:%v", suiteN+".te", err)
		}
	}
	suiteF, err := os.Open(suiteN+".json");
	log.Infof("Loading test suite from: %s", 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", *sc); err != nil {}
			if err := t.ExecuteTemplate(f, "server.go", *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", *sc); err != nil {}
		if err := t.ExecuteTemplate(f, "serverInit.go", 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", 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", *sc); err != nil {}
		if err := t.ExecuteTemplate(f, "clientInit.go", 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", 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", 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", 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",
														"../templates/serverInit.go",
														"../templates/client.go",
														"../templates/clientInit.go",
														"../templates/runTests.go",
														"../templates/stats.go",
														"../templates/main.go"))
		// 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", 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", 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",
					"../templates/stats.go"))
	if f,err := os.Create(srcDir+"/runAll.go"); err == nil {
		if err := t.ExecuteTemplate(f, "runAll.go", 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", 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
}

