package vsync

// Used to ease the setup of Veyron Sync test scenarios.
// Parses a sync command file and returns a vector of commands to execute.
//
// Used by different test replay engines:
// - dagReplayCommands() executes the parsed commands at the DAG API level.
// - logReplayCommands() executes the parsed commands at the Log API level.

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"os"
	"strconv"
	"strings"

	"veyron2/storage"
)

const (
	addLocal = iota
	addRemote
	setDevTable
	linkLocal
	linkRemote
)

type syncCommand struct {
	cmd     int
	objID   storage.ID
	version storage.Version
	parents []storage.Version
	logrec  string
	devID   DeviceID
	genVec  GenVector
}

func strToObjID(objStr string) (storage.ID, error) {
	var objID storage.ID
	id, err := strconv.ParseUint(objStr, 10, 64)
	if err != nil {
		return objID, err
	}
	idbuf := make([]byte, len(objID))
	if binary.PutUvarint(idbuf, id) == 0 {
		return objID, fmt.Errorf("cannot store ID %d into a binary buffer", id)
	}
	for i := 0; i < len(objID); i++ {
		objID[i] = idbuf[i]
	}
	return objID, nil
}

func strToVersion(verStr string) (storage.Version, error) {
	ver, err := strconv.ParseUint(verStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return storage.Version(ver), nil
}

func strToGenID(genIDStr string) (GenID, error) {
	id, err := strconv.ParseUint(genIDStr, 10, 64)
	if err != nil {
		return 0, err
	}
	return GenID(id), nil
}

func parseSyncCommands(file string) ([]syncCommand, error) {
	cmds := []syncCommand{}
	sf, err := os.Open("testdata/" + file)
	if err != nil {
		return nil, err
	}
	defer sf.Close()

	scanner := bufio.NewScanner(sf)
	lineno := 0
	for scanner.Scan() {
		lineno++
		line := strings.TrimSpace(scanner.Text())
		if line == "" || line[0] == '#' {
			continue
		}

		args := strings.Split(line, "|")
		nargs := len(args)

		switch args[0] {
		case "addl", "addr":
			expNargs := 6
			if nargs != expNargs {
				return nil, fmt.Errorf("%s:%d: need %d args instead of %d", file, lineno, expNargs, nargs)
			}
			version, err := strToVersion(args[2])
			if err != nil {
				return nil, fmt.Errorf("%s:%d: invalid version: %s", file, lineno, args[2])
			}
			var parents []storage.Version
			for i := 3; i <= 4; i++ {
				if args[i] != "" {
					pver, err := strToVersion(args[i])
					if err != nil {
						return nil, fmt.Errorf("%s:%d: invalid parent: %s", file, lineno, args[i])
					}
					parents = append(parents, pver)
				}
			}

			cmd := syncCommand{version: version, parents: parents, logrec: args[5]}
			if args[0] == "addl" {
				cmd.cmd = addLocal
			} else {
				cmd.cmd = addRemote
			}
			if cmd.objID, err = strToObjID(args[1]); err != nil {
				return nil, fmt.Errorf("%s:%d: invalid object ID: %s", file, lineno, args[1])
			}
			cmds = append(cmds, cmd)

		case "setdev":
			expNargs := 3
			if nargs != expNargs {
				return nil, fmt.Errorf("%s:%d: need %d args instead of %d", file, lineno, expNargs, nargs)
			}

			genVec := make(GenVector)
			for _, elem := range strings.Split(args[2], ",") {
				kv := strings.Split(elem, ":")
				if len(kv) != 2 {
					return nil, fmt.Errorf("%s:%d: invalid gen vector key/val: %s", file, lineno, elem)
				}
				genID, err := strToGenID(kv[1])
				if err != nil {
					return nil, fmt.Errorf("%s:%d: invalid gen ID: %s", file, lineno, kv[1])
				}
				genVec[DeviceID(kv[0])] = genID
			}

			cmd := syncCommand{cmd: setDevTable, devID: DeviceID(args[1]), genVec: genVec}
			cmds = append(cmds, cmd)

		case "linkl", "linkr":
			expNargs := 6
			if nargs != expNargs {
				return nil, fmt.Errorf("%s:%d: need %d args instead of %d", file, lineno, expNargs, nargs)
			}

			version, err := strToVersion(args[2])
			if err != nil {
				return nil, fmt.Errorf("%s:%d: invalid version: %s", file, lineno, args[2])
			}
			if args[3] == "" {
				return nil, fmt.Errorf("%s:%d: parent (to-node) version not specified", file, lineno)
			}
			if args[4] != "" {
				return nil, fmt.Errorf("%s:%d: cannot specify a 2nd parent (to-node): %s", file, lineno, args[4])
			}
			parent, err := strToVersion(args[3])
			if err != nil {
				return nil, fmt.Errorf("%s:%d: invalid parent (to-node) version: %s", file, lineno, args[3])
			}

			cmd := syncCommand{version: version, parents: []storage.Version{parent}, logrec: args[5]}
			if args[0] == "linkl" {
				cmd.cmd = linkLocal
			} else {
				cmd.cmd = linkRemote
			}
			if cmd.objID, err = strToObjID(args[1]); err != nil {
				return nil, fmt.Errorf("%s:%d: invalid object ID: %s", file, lineno, args[1])
			}
			cmds = append(cmds, cmd)

		default:
			return nil, fmt.Errorf("%s:%d: invalid operation: %s", file, lineno, args[0])
		}
	}

	err = scanner.Err()
	return cmds, err
}

func dagReplayCommands(dag *dag, syncfile string) error {
	cmds, err := parseSyncCommands(syncfile)
	if err != nil {
		return err
	}

	for _, cmd := range cmds {
		switch cmd.cmd {
		case addLocal:
			if err = dag.addNode(cmd.objID, cmd.version, false, cmd.parents, cmd.logrec); err != nil {
				return fmt.Errorf("cannot add local node %d:%d to DAG: %v", cmd.objID, cmd.version, err)
			}
			if err := dag.moveHead(cmd.objID, cmd.version); err != nil {
				return fmt.Errorf("cannot move head to %d:%d in DAG: %v", cmd.objID, cmd.version, err)
			}
			dag.flush()

		case addRemote:
			if err = dag.addNode(cmd.objID, cmd.version, true, cmd.parents, cmd.logrec); err != nil {
				return fmt.Errorf("cannot add remote node %d:%d to DAG: %v", cmd.objID, cmd.version, err)
			}
			dag.flush()

		case linkLocal:
			if err = dag.addParent(cmd.objID, cmd.version, cmd.parents[0], false); err != nil {
				return fmt.Errorf("cannot add local parent %d to DAG node %d:%d: %v",
					cmd.parents[0], cmd.objID, cmd.version, err)
			}
			dag.flush()

		case linkRemote:
			if err = dag.addParent(cmd.objID, cmd.version, cmd.parents[0], true); err != nil {
				return fmt.Errorf("cannot add remote parent %d to DAG node %d:%d: %v",
					cmd.parents[0], cmd.objID, cmd.version, err)
			}
			dag.flush()
		}
	}
	return nil
}
