package main

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"

	"github.com/edwarnicke/exechelper"
)

const configTemplate = `unix {
  nodaemon
  log %[1]s/var/log/vpp/vpp.log
  full-coredump
  cli-listen %[1]s/var/run/vpp/cli.sock
  runtime-dir %[1]s/var/run
  gid vpp
}

api-trace {
  on
}

api-segment {
  gid vpp
}

socksvr {
  socket-name %[1]s/var/run/vpp/api.sock
}

statseg {
  socket-name %[1]s/var/run/vpp/stats.sock
}

plugins {
	plugin unittest_plugin.so { enable }
    plugin dpdk_plugin.so { disable }
    plugin crypto_aesni_plugin.so { enable }
    plugin quic_plugin.so { enable }
}

`

const TopologyDir string = "topo/"

type Stanza struct {
	content string
	pad     int
}

type ActionResult struct {
	Err       error
	Desc      string
	ErrOutput string
	StdOutput string
}

type JsonResult struct {
	Code      int
	Desc      string
	ErrOutput string
	StdOutput string
}

func StartServerApp(running chan error, done chan struct{}, env []string) {
	cmd := exec.Command("iperf3", "-4", "-s")
	if env != nil {
		cmd.Env = env
	}
	err := cmd.Start()
	if err != nil {
		msg := fmt.Errorf("failed to start iperf server: %v", err)
		running <- msg
		return
	}
	running <- nil
	<-done
	cmd.Process.Kill()
}

func StartClientApp(env []string, clnCh chan error) {
	defer func() {
		clnCh <- nil
	}()

	nTries := 0

	for {
		cmd := exec.Command("iperf3", "-c", "10.10.10.1", "-u", "-l", "1460", "-b", "10g")
		if env != nil {
			cmd.Env = env
		}
		o, err := cmd.CombinedOutput()
		if err != nil {
			if nTries > 5 {
				clnCh <- fmt.Errorf("failed to start client app '%s'.\n%s", err, o)
				return
			}
			time.Sleep(1 * time.Second)
			nTries++
			continue
		} else {
			fmt.Printf("Client output: %s", o)
		}
		break
	}
}

// run vpphelper in docker
func hstExec(args string, instance string) (string, error) {
	syncFile := fmt.Sprintf("/tmp/%s/sync/rc", instance)
	os.Remove(syncFile)

	c := "docker exec -d " + instance + " /hs-test " + args
	err := exechelper.Run(c)
	if err != nil {
		return "", err
	}

	res, err := waitForSyncFile(syncFile)

	if err != nil {
		return "", fmt.Errorf("failed to read sync file while executing './hs-test %s': %v", args, err)
	}

	o := res.StdOutput + res.ErrOutput
	if res.Code != 0 {
		return o, fmt.Errorf("cmd resulted in non-zero value %d: %s", res.Code, res.Desc)
	}
	return o, err
}

func waitForSyncFile(fname string) (*JsonResult, error) {
	var res JsonResult

	for i := 0; i < 60; i++ {
		f, err := os.Open(fname)
		if err == nil {
			defer f.Close()

			data, err := ioutil.ReadFile(fname)
			if err != nil {
				return nil, fmt.Errorf("read error: %v", err)
			}
			err = json.Unmarshal(data, &res)
			if err != nil {
				return nil, fmt.Errorf("json unmarshal error: %v", err)
			}
			return &res, nil
		}
		time.Sleep(1 * time.Second)
	}
	return nil, fmt.Errorf("no sync file found")
}

func dockerRun(instance, args string) error {
	exechelper.Run(fmt.Sprintf("mkdir -p /tmp/%s/sync", instance))
	syncPath := fmt.Sprintf("-v /tmp/%s/sync:/tmp/sync", instance)
	cmd := "docker run --cap-add=all -d --privileged --network host --rm "
	cmd += syncPath
	cmd += " " + args
	cmd += " --name " + instance + " hs-test/vpp"
	fmt.Println(cmd)
	return exechelper.Run(cmd)
}

func assertFileSize(f1, f2 string) error {
	fi1, err := os.Stat(f1)
	if err != nil {
		return err
	}

	fi2, err1 := os.Stat(f2)
	if err1 != nil {
		return err1
	}

	if fi1.Size() != fi2.Size() {
		return fmt.Errorf("file sizes differ (%d vs %d)", fi1.Size(), fi2.Size())
	}
	return nil
}

func dockerExec(cmd string, instance string) ([]byte, error) {
	c := "docker exec -d " + instance + " " + cmd
	return exechelper.CombinedOutput(c)
}

func startEnvoy(ctx context.Context, dockerInstance string) <-chan error {
	errCh := make(chan error)
	wd, err := os.Getwd()
	if err != nil {
		errCh <- err
		return errCh
	}

	c := []string{"docker", "run", "--rm", "--name", "envoy",
		"-v", fmt.Sprintf("%s/envoy/proxy.yaml:/etc/envoy/envoy.yaml", wd),
		"-v", fmt.Sprintf("shared-vol:/tmp/%s", dockerInstance),
		"-v", fmt.Sprintf("%s/envoy:/tmp", wd),
		"-e", "ENVOY_UID=0",
		"-e", "VCL_CONFIG=/tmp/vcl.conf",
		"envoyproxy/envoy-contrib:v1.21-latest"}
	fmt.Println(c)

	go func(errCh chan error) {
		count := 0
		var cmd *exec.Cmd
		for ; ; count++ {
			cmd = NewCommand(c, "")
			err = cmd.Start()
			if err == nil {
				break
			}
			if count > 5 {
				errCh <- fmt.Errorf("failed to start envoy docker after %d attempts", count)
				return
			}
		}

		err = cmd.Wait()
		if err != nil {
			errCh <- fmt.Errorf("failed to start docker: %v", err)
			return
		}
		<-ctx.Done()
	}(errCh)
	return errCh
}

func setupEnvoy(t *testing.T, ctx context.Context, dockerInstance string) error {
	errCh := startEnvoy(ctx, dockerInstance)
	select {
	case err := <-errCh:
		return err
	default:
	}

	go func(ctx context.Context, errCh <-chan error) {
		for {
			select {
			// handle cancel() call from outside to gracefully stop the routine
			case <-ctx.Done():
				return
			default:
				select {
				case err := <-errCh:
					fmt.Printf("error while running envoy: %v", err)
				default:
				}
			}
		}
	}(ctx, errCh)
	return nil
}

func configureVppProxy() error {
	_, err := dockerExec("vppctl test proxy server server-uri tcp://10.0.0.2/555 client-uri tcp://10.0.1.1/666",
		"vpp-proxy")
	if err != nil {
		return fmt.Errorf("error while configuring vpp proxy test: %v", err)
	}
	return nil
}

func startHttpServer(running chan struct{}, done chan struct{}, addressPort, netNs string) {
	cmd := NewCommand([]string{"./http_server", addressPort}, netNs)
	err := cmd.Start()
	if err != nil {
		fmt.Println("Failed to start http server")
		return
	}
	running <- struct{}{}
	<-done
	cmd.Process.Kill()
}

func startWget(finished chan error, server_ip, port string, netNs string) {
	fname := "test_file_10M"
	defer func() {
		finished <- errors.New("wget error")
	}()

	cmd := NewCommand([]string{"wget", "--tries=5", "-q", "-O", "/dev/null", server_ip + ":" + port + "/" + fname},
		netNs)
	o, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Printf("wget error: '%s'.\n%s", err, o)
		return
	}
	fmt.Printf("Client output: %s", o)
	finished <- nil
}

func (c *Stanza) NewStanza(name string) *Stanza {
	c.Append("\n" + name + " {")
	c.pad += 2
	return c
}

func (c *Stanza) Append(name string) *Stanza {
	c.content += strings.Repeat(" ", c.pad)
	c.content += name + "\n"
	return c
}

func (c *Stanza) Close() *Stanza {
	c.content += "}\n"
	c.pad -= 2
	return c
}

func (s *Stanza) ToString() string {
	return s.content
}

func (s *Stanza) SaveToFile(fileName string) error {
	fo, err := os.Create(fileName)
	if err != nil {
		return err
	}
	defer fo.Close()

	_, err = io.Copy(fo, strings.NewReader(s.content))
	return err
}
