// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .

package main

import (
	"bytes"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"strings"
	"unicode"

	"v.io/v23/vdl"
	"v.io/v23/vom"
	"v.io/x/lib/cmdline"
)

func main() {
	cmdline.Main(cmdVom)
}

var cmdVom = &cmdline.Command{
	Name:  "vom",
	Short: "helps debug the Vanadium Object Marshaling wire protocol",
	Long: `
Command vom helps debug the Vanadium Object Marshaling wire protocol.
`,
	Children: []*cmdline.Command{cmdDecode, cmdDump},
}

var cmdDecode = &cmdline.Command{
	Runner: cmdline.RunnerFunc(runDecode),
	Name:   "decode",
	Short:  "Decode data encoded in the vom format",
	Long: `
Decode decodes data encoded in the vom format.  If no arguments are provided,
decode reads the data from stdin, otherwise the argument is the data.

By default the data is assumed to be represented in hex, with all whitespace
anywhere in the data ignored.  Use the -data flag to specify other data
representations.

`,
	ArgsName: "[data]",
	ArgsLong: "[data] is the data to decode; if not specified, reads from stdin",
}

var cmdDump = &cmdline.Command{
	Runner: cmdline.RunnerFunc(runDump),
	Name:   "dump",
	Short:  "Dump data encoded in the vom format into formatted output",
	Long: `
Dump dumps data encoded in the vom format, generating formatted output
describing each portion of the encoding.  If no arguments are provided, dump
reads the data from stdin, otherwise the argument is the data.

By default the data is assumed to be represented in hex, with all whitespace
anywhere in the data ignored.  Use the -data flag to specify other data
representations.

Calling "vom dump" with no flags and no arguments combines the default stdin
mode with the default hex mode.  This default mode is special; certain non-hex
characters may be input to represent commands:
  . (period)    Calls Dumper.Status to get the current decoding status.
  ; (semicolon) Calls Dumper.Flush to flush output and start a new message.

This lets you cut-and-paste hex strings into your terminal, and use the commands
to trigger status or flush calls; i.e. a rudimentary debugging UI.

See v.io/v23/vom.Dumper for details on the dump output.
`,
	ArgsName: "[data]",
	ArgsLong: "[data] is the data to dump; if not specified, reads from stdin",
}

var (
	flagDataRep = dataRepHex
)

func init() {
	cmdDecode.Flags.Var(&flagDataRep, "data",
		"Data representation, one of "+fmt.Sprint(dataRepAll))
	cmdDump.Flags.Var(&flagDataRep, "data",
		"Data representation, one of "+fmt.Sprint(dataRepAll))
}

func runDecode(env *cmdline.Env, args []string) error {
	// Convert all inputs into a reader over binary bytes.
	var data string
	switch {
	case len(args) > 1:
		return env.UsageErrorf("too many args")
	case len(args) == 1:
		data = args[0]
	default:
		bytes, err := ioutil.ReadAll(os.Stdin)
		if err != nil {
			return err
		}
		data = string(bytes)
	}
	binbytes, err := dataToBinaryBytes(data)
	if err != nil {
		return err
	}
	reader := bytes.NewBuffer(binbytes)
	// Decode the binary bytes.
	// TODO(toddw): Add a flag to set a specific type to decode into.
	decoder := vom.NewDecoder(reader)
	var result *vdl.Value
	if err := decoder.Decode(&result); err != nil {
		return err
	}
	fmt.Fprintln(env.Stdout, result)
	if reader.Len() != 0 {
		return fmt.Errorf("%d leftover bytes: % x", reader.Len(), reader.String())
	}
	return nil
}

func runDump(env *cmdline.Env, args []string) error {
	// Handle non-streaming cases.
	switch {
	case len(args) > 1:
		return env.UsageErrorf("too many args")
	case len(args) == 1:
		binbytes, err := dataToBinaryBytes(args[0])
		if err != nil {
			return err
		}
		fmt.Fprintln(env.Stdout, vom.Dump(binbytes))
		return nil
	}
	// Handle streaming from stdin.
	dumper := vom.NewDumper(vom.NewDumpWriter(env.Stdout))
	defer dumper.Close()
	// Handle simple non-hex cases.
	switch flagDataRep {
	case dataRepBinary:
		_, err := io.Copy(dumper, os.Stdin)
		return err
	}
	return runDumpHexStream(dumper)
}

// runDumpHexStream handles the hex stdin-streaming special-case, with commands
// for status and flush.  This is tricky because we need to strip whitespace,
// handle commands where they appear in the stream, and deal with the fact that
// it takes two hex characters to encode a single byte.
//
// The strategy is to run a ReadLoop that reads into a reasonably-sized buffer.
// Inside the ReadLoop we take the buffer, strip whitespace, and keep looping to
// process all data up to each command, and then process the command.  If a
// command appears in the middle of two hex characters representing a byte, we
// send the command first, before sending the byte.
//
// Any leftover non-command single byte is stored in buf and bufStart is set, so
// that the next iteration of ReadLoop can read after those bytes.
func runDumpHexStream(dumper *vom.Dumper) error {
	buf := make([]byte, 1024)
	bufStart := 0
ReadLoop:
	for {
		n, err := os.Stdin.Read(buf[bufStart:])
		switch {
		case n == 0 && err == io.EOF:
			return nil
		case n == 0 && err != nil:
			return err
		}
		// We may have hex interspersed with spaces and commands.  The strategy is
		// to strip all whitespace, and process each even-sized chunk of hex bytes
		// up to a command or the end of the buffer.
		//
		// Data that appears before a command is written before the command, and
		// data after the command is written after.  But if a command appears in the
		// middle of two hex characters representing a byte, we send the command
		// first, before sending the byte.
		hexbytes := bytes.Map(dropWhitespace, buf[:bufStart+n])
		for len(hexbytes) > 0 {
			end := len(hexbytes)
			cmdIndex := bytes.IndexAny(hexbytes, ".;")
			if cmdIndex != -1 {
				end = cmdIndex
			} else if end == 1 {
				// We have a single non-command byte left in hexbytes; copy it into buf
				// and set bufStart.
				copy(buf, hexbytes[0:1])
				bufStart = 1
				continue ReadLoop
			}
			if end%2 == 1 {
				end -= 1 // Ensure the end is on an even boundary.
			}
			// Write this even-sized chunk of hex bytes to the dumper.
			binbytes, err := hex.DecodeString(string(hexbytes[:end]))
			if err != nil {
				return err
			}
			if _, err := dumper.Write(binbytes); err != nil {
				return err
			}
			// Handle commands.
			if cmdIndex != -1 {
				switch cmd := hexbytes[cmdIndex]; cmd {
				case '.':
					dumper.Status()
				case ';':
					dumper.Flush()
				default:
					return fmt.Errorf("unhandled command %q", cmd)
				}
				// Move data after the command forward.
				copy(hexbytes[cmdIndex:], hexbytes[cmdIndex+1:])
				hexbytes = hexbytes[:len(hexbytes)-1]
			}
			// Move data after the end forward.
			copy(hexbytes, hexbytes[end:])
			hexbytes = hexbytes[:len(hexbytes)-end]
		}
		bufStart = 0
	}
}

func dataToBinaryBytes(data string) ([]byte, error) {
	// Transform all data representations to binary.
	switch flagDataRep {
	case dataRepHex:
		// Remove all whitespace out of the hex string.
		binbytes, err := hex.DecodeString(strings.Map(dropWhitespace, data))
		if err != nil {
			return nil, err
		}
		return binbytes, nil
	}
	return []byte(data), nil
}

func dropWhitespace(r rune) rune {
	if unicode.IsSpace(r) {
		return -1
	}
	return r
}
