package main

import (
	"bytes"
	"context"
	"fmt"
	"os"
	"path/filepath"

	"git.fd.io/govpp.git/api"
	"github.com/edwarnicke/exechelper"
	"github.com/edwarnicke/govpp/binapi/af_packet"
	"github.com/edwarnicke/govpp/binapi/ethernet_types"
	interfaces "github.com/edwarnicke/govpp/binapi/interface"
	"github.com/edwarnicke/govpp/binapi/interface_types"
	ip_types "github.com/edwarnicke/govpp/binapi/ip_types"
	"github.com/edwarnicke/govpp/binapi/session"
	"github.com/edwarnicke/govpp/binapi/tapv2"
	"github.com/edwarnicke/govpp/binapi/vlib"
	"github.com/edwarnicke/vpphelper"
)

var (
	workDir, _ = os.Getwd()
)

type ConfFn func(context.Context, api.Connection) error

type Actions struct {
}

func configureProxyTcp(ifName0, ipAddr0, ifName1, ipAddr1 string) ConfFn {
	return func(ctx context.Context,
		vppConn api.Connection) error {

		_, err := configureAfPacket(ctx, vppConn, ifName0, ipAddr0)
		if err != nil {
			fmt.Printf("failed to create af packet: %v", err)
			return err
		}
		_, err = configureAfPacket(ctx, vppConn, ifName1, ipAddr1)
		if err != nil {
			fmt.Printf("failed to create af packet: %v", err)
			return err
		}
		return nil
	}
}

func (a *Actions) RunHttpCliSrv(args []string) *ActionResult {
	cmd := fmt.Sprintf("http cli server")
	return ApiCliInband(workDir, cmd)
}

func (a *Actions) RunHttpCliCln(args []string) *ActionResult {
	cmd := fmt.Sprintf("http cli client uri http://10.10.10.1/80 query %s", getArgs())
	fmt.Println(cmd)
	return ApiCliInband(workDir, cmd)
}

func (a *Actions) ConfigureVppProxy(args []string) *ActionResult {
	ctx, cancel := newVppContext()
	defer cancel()

	con, vppErrCh := vpphelper.StartAndDialContext(ctx,
		vpphelper.WithVppConfig(configTemplate),
		vpphelper.WithRootDir(workDir))
	exitOnErrCh(ctx, cancel, vppErrCh)

	confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
	err := confFn(ctx, con)
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}
	writeSyncFile(OkResult())
	<-ctx.Done()
	return nil
}

func (a *Actions) ConfigureEnvoyProxy(args []string) *ActionResult {
	var startup Stanza
	startup.
		NewStanza("session").
		Append("enable").
		Append("use-app-socket-api").
		Append("evt_qs_memfd_seg").
		Append("event-queue-length 100000").Close()
	ctx, cancel := newVppContext()
	defer cancel()

	con, vppErrCh := vpphelper.StartAndDialContext(ctx,
		vpphelper.WithVppConfig(configTemplate+startup.ToString()),
		vpphelper.WithRootDir(workDir))
	exitOnErrCh(ctx, cancel, vppErrCh)

	confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
	err := confFn(ctx, con)
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}
	err0 := exechelper.Run("chmod 777 -R " + workDir)
	if err0 != nil {
		return NewActionResult(err, ActionResultWithDesc("setting permissions failed"))
	}
	writeSyncFile(OkResult())
	<-ctx.Done()
	return nil
}

func getArgs() string {
	s := ""
	for i := 2; i < len(os.Args); i++ {
		s = s + " " + os.Args[i]
	}
	return s
}

func ApiCliInband(root, cmd string) *ActionResult {
	ctx, _ := newVppContext()
	con := vpphelper.DialContext(ctx, filepath.Join(root, "/var/run/vpp/api.sock"))
	cliInband := vlib.CliInband{Cmd: cmd}
	cliInbandReply, err := vlib.NewServiceClient(con).CliInband(ctx, &cliInband)
	return NewActionResult(err, ActionResultWithStdout(cliInbandReply.Reply))
}

func (a *Actions) RunEchoClient(args []string) *ActionResult {
	outBuff := bytes.NewBuffer([]byte{})
	errBuff := bytes.NewBuffer([]byte{})

	cmd := fmt.Sprintf("vpp_echo client socket-name %s/var/run/app_ns_sockets/2 use-app-socket-api uri %s://10.10.10.1/12344", workDir, args[2])
	err := exechelper.Run(cmd,
		exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
		exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))

	return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
		ActionResultWithStderr(string(errBuff.String())))
}

func (a *Actions) RunEchoServer(args []string) *ActionResult {
	cmd := fmt.Sprintf("vpp_echo server TX=RX socket-name %s/var/run/app_ns_sockets/1 use-app-socket-api uri %s://10.10.10.1/12344", workDir, args[2])
	errCh := exechelper.Start(cmd)
	select {
	case err := <-errCh:
		writeSyncFile(NewActionResult(err, ActionResultWithDesc("echo_server: ")))
	default:
	}
	writeSyncFile(OkResult())
	return nil
}

func (a *Actions) RunEchoSrvInternal(args []string) *ActionResult {
	cmd := fmt.Sprintf("test echo server %s uri tcp://10.10.10.1/1234", getArgs())
	return ApiCliInband(workDir, cmd)
}

func (a *Actions) RunEchoClnInternal(args []string) *ActionResult {
	cmd := fmt.Sprintf("test echo client %s uri tcp://10.10.10.1/1234", getArgs())
	return ApiCliInband(workDir, cmd)
}

func (a *Actions) RunVclEchoServer(args []string) *ActionResult {
	f, err := os.Create("vcl_1.conf")
	if err != nil {
		return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
	}
	socketPath := fmt.Sprintf("%s/var/run/app_ns_sockets/1", workDir)
	fmt.Fprintf(f, vclTemplate, socketPath, "1")
	f.Close()

	os.Setenv("VCL_CONFIG", "./vcl_1.conf")
	cmd := fmt.Sprintf("vcl_test_server -p %s 12346", args[2])
	errCh := exechelper.Start(cmd)
	select {
	case err := <-errCh:
		writeSyncFile(NewActionResult(err, ActionResultWithDesc("vcl_test_server: ")))
	default:
	}
	writeSyncFile(OkResult())
	return nil
}

func (a *Actions) RunVclEchoClient(args []string) *ActionResult {
	outBuff := bytes.NewBuffer([]byte{})
	errBuff := bytes.NewBuffer([]byte{})

	f, err := os.Create("vcl_2.conf")
	if err != nil {
		return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
	}
	socketPath := fmt.Sprintf("%s/var/run/app_ns_sockets/2", workDir)
	fmt.Fprintf(f, vclTemplate, socketPath, "2")
	f.Close()

	os.Setenv("VCL_CONFIG", "./vcl_2.conf")
	cmd := fmt.Sprintf("vcl_test_client -U -p %s 10.10.10.1 12346", args[2])
	err = exechelper.Run(cmd,
		exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
		exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))

	return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
		ActionResultWithStderr(string(errBuff.String())))
}

func configure2vethsTopo(ifName, interfaceAddress, namespaceId string, secret uint64, optionalHardwareAddress ...string) ConfFn {
	return func(ctx context.Context,
		vppConn api.Connection) error {

		var swIfIndex interface_types.InterfaceIndex
		var err error
		if optionalHardwareAddress == nil {
			swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress)
		} else {
			swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress, optionalHardwareAddress[0])
		}
		if err != nil {
			fmt.Printf("failed to create af packet: %v", err)
		}
		_, er := session.NewServiceClient(vppConn).AppNamespaceAddDelV2(ctx, &session.AppNamespaceAddDelV2{
			Secret:      secret,
			SwIfIndex:   swIfIndex,
			NamespaceID: namespaceId,
		})
		if er != nil {
			fmt.Printf("add app namespace: %v", err)
			return err
		}

		_, er1 := session.NewServiceClient(vppConn).SessionEnableDisable(ctx, &session.SessionEnableDisable{
			IsEnable: true,
		})
		if er1 != nil {
			fmt.Printf("session enable %v", err)
			return err
		}
		return nil
	}
}

func (a *Actions) Configure2Veths(args []string) *ActionResult {
	var startup Stanza
	startup.
		NewStanza("session").
		Append("enable").
		Append("use-app-socket-api").Close()

	ctx, cancel := newVppContext()
	defer cancel()

	vppConfig, err := deserializeVppConfig(args[2])
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("deserializing configuration failed"))
	}

	con, vppErrCh := vpphelper.StartAndDialContext(ctx,
		vpphelper.WithVppConfig(vppConfig.getTemplate()+startup.ToString()),
		vpphelper.WithRootDir(workDir))
	exitOnErrCh(ctx, cancel, vppErrCh)

	var fn func(context.Context, api.Connection) error
	switch vppConfig.Variant {
	case "srv":
		fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1)
	case "srv-with-preset-hw-addr":
		fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1, "00:00:5e:00:53:01")
	case "cln":
		fallthrough
	default:
		fn = configure2vethsTopo("vppcln", "10.10.10.2/24", "2", 2)
	}
	err = fn(ctx, con)
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}
	writeSyncFile(OkResult())
	<-ctx.Done()
	return nil
}

func configureAfPacket(ctx context.Context, vppCon api.Connection,
	name, interfaceAddress string, optionalHardwareAddress ...string) (interface_types.InterfaceIndex, error) {
	var err error
	ifaceClient := interfaces.NewServiceClient(vppCon)
	afPacketCreate := af_packet.AfPacketCreateV2{
		UseRandomHwAddr: true,
		HostIfName:      name,
		NumRxQueues:     1,
	}
	if len(optionalHardwareAddress) > 0 {
		afPacketCreate.HwAddr, err = ethernet_types.ParseMacAddress(optionalHardwareAddress[0])
		if err != nil {
			fmt.Printf("failed to parse mac address: %v", err)
			return 0, err
		}
		afPacketCreate.UseRandomHwAddr = false
	}
	afPacketCreateRsp, err := af_packet.NewServiceClient(vppCon).AfPacketCreateV2(ctx, &afPacketCreate)
	if err != nil {
		fmt.Printf("failed to create af packet: %v", err)
		return 0, err
	}
	_, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
		SwIfIndex: afPacketCreateRsp.SwIfIndex,
		Flags:     interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
	})
	if err != nil {
		fmt.Printf("set interface state up failed: %v\n", err)
		return 0, err
	}
	ipPrefix, err := ip_types.ParseAddressWithPrefix(interfaceAddress)
	if err != nil {
		fmt.Printf("parse ip address %v\n", err)
		return 0, err
	}
	ipAddress := &interfaces.SwInterfaceAddDelAddress{
		IsAdd:     true,
		SwIfIndex: afPacketCreateRsp.SwIfIndex,
		Prefix:    ipPrefix,
	}
	_, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
	if errx != nil {
		fmt.Printf("add ip address %v\n", err)
		return 0, err
	}
	return afPacketCreateRsp.SwIfIndex, nil
}

func (a *Actions) ConfigureHttpTps(args []string) *ActionResult {
	ctx, cancel := newVppContext()
	defer cancel()
	con, vppErrCh := vpphelper.StartAndDialContext(ctx,
		vpphelper.WithVppConfig(configTemplate))
	exitOnErrCh(ctx, cancel, vppErrCh)

	confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
	err := confFn(ctx, con)
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}

	_, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
		IsEnable: true,
	})
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}
	Vppcli("", "http tps uri tcp://0.0.0.0/8080")
	writeSyncFile(OkResult())
	<-ctx.Done()
	return nil
}

func (a *Actions) ConfigureTap(args []string) *ActionResult {
	var startup Stanza
	startup.
		NewStanza("session").
		Append("enable").
		Append("use-app-socket-api").Close()

	ctx, cancel := newVppContext()
	defer cancel()
	con, vppErrCh := vpphelper.StartAndDialContext(ctx,
		vpphelper.WithRootDir(workDir),
		vpphelper.WithVppConfig(configTemplate+startup.ToString()))
	exitOnErrCh(ctx, cancel, vppErrCh)
	ifaceClient := interfaces.NewServiceClient(con)

	pref, err := ip_types.ParseIP4Prefix("10.10.10.2/24")
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("failed to parse ip4 address"))
	}
	createTapReply, err := tapv2.NewServiceClient(con).TapCreateV2(ctx, &tapv2.TapCreateV2{
		HostIfNameSet:    true,
		HostIfName:       "tap0",
		HostIP4PrefixSet: true,
		HostIP4Prefix:    ip_types.IP4AddressWithPrefix(pref),
	})
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("failed to configure tap"))
	}
	ipPrefix, err := ip_types.ParseAddressWithPrefix("10.10.10.1/24")
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("parsing ip address failed"))
	}
	ipAddress := &interfaces.SwInterfaceAddDelAddress{
		IsAdd:     true,
		SwIfIndex: createTapReply.SwIfIndex,
		Prefix:    ipPrefix,
	}
	_, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
	if errx != nil {
		return NewActionResult(err, ActionResultWithDesc("configuring ip address failed"))
	}
	_, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
		SwIfIndex: createTapReply.SwIfIndex,
		Flags:     interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
	})
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("failed to set interface state"))
	}
	_, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
		IsEnable: true,
	})
	if err != nil {
		return NewActionResult(err, ActionResultWithDesc("configuration failed"))
	}
	writeSyncFile(OkResult())
	<-ctx.Done()
	return nil
}
