// 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.

package writer

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
	"unicode/utf8"

	"v.io/v23/syncbase/nosql"
	"v.io/v23/vdl"
	vtime "v.io/v23/vdlroot/time"
)

type Justification int

const (
	Unknown Justification = iota
	Left
	Right
)

// WriteTable formats the results as ASCII tables.
func WriteTable(out io.Writer, columnNames []string, rs nosql.ResultStream) error {
	// Buffer the results so we can compute the column widths.
	columnWidths := make([]int, len(columnNames))
	for i, cName := range columnNames {
		columnWidths[i] = utf8.RuneCountInString(cName)
	}
	justification := make([]Justification, len(columnNames))
	var results [][]string
	for rs.Advance() {
		row := make([]string, len(columnNames))
		for i, column := range rs.Result() {
			if i >= len(columnNames) {
				return errors.New("more columns in result than in columnNames")
			}
			if justification[i] == Unknown {
				justification[i] = getJustification(column)
			}
			columnStr := toString(column, false)
			row[i] = columnStr
			columnLen := utf8.RuneCountInString(columnStr)
			if columnLen > columnWidths[i] {
				columnWidths[i] = columnLen
			}
		}
		results = append(results, row)
	}
	if rs.Err() != nil {
		return rs.Err()
	}

	writeBorder(out, columnWidths)
	sep := "| "
	for i, cName := range columnNames {
		io.WriteString(out, fmt.Sprintf("%s%*s", sep, columnWidths[i], cName))
		sep = " | "
	}
	io.WriteString(out, " |\n")
	writeBorder(out, columnWidths)
	for _, result := range results {
		sep = "| "
		for i, column := range result {
			if justification[i] == Right {
				io.WriteString(out, fmt.Sprintf("%s%*s", sep, columnWidths[i], column))
			} else {
				io.WriteString(out, fmt.Sprintf("%s%-*s", sep, columnWidths[i], column))
			}
			sep = " | "
		}
		io.WriteString(out, " |\n")
	}
	writeBorder(out, columnWidths)
	return nil
}

func writeBorder(out io.Writer, columnWidths []int) {
	sep := "+-"
	for _, width := range columnWidths {
		io.WriteString(out, fmt.Sprintf("%s%s", sep, strings.Repeat("-", width)))
		sep = "-+-"
	}
	io.WriteString(out, "-+\n")
}

func getJustification(val *vdl.Value) Justification {
	switch val.Kind() {
	// TODO(kash): Floating point numbers should have the decimal point line up.
	case vdl.Bool, vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64,
		vdl.Float32, vdl.Float64, vdl.Complex64, vdl.Complex128:
		return Right
	// TODO(kash): Leave nil values as unknown.
	default:
		return Left
	}
}

// WriteCSV formats the results as CSV as specified by https://tools.ietf.org/html/rfc4180.
func WriteCSV(out io.Writer, columnNames []string, rs nosql.ResultStream, delimiter string) error {
	delim := ""
	for _, cName := range columnNames {
		str := doubleQuoteForCSV(cName, delimiter)
		io.WriteString(out, fmt.Sprintf("%s%s", delim, str))
		delim = delimiter
	}
	io.WriteString(out, "\n")
	for rs.Advance() {
		delim := ""
		for _, column := range rs.Result() {
			str := doubleQuoteForCSV(toString(column, false), delimiter)
			io.WriteString(out, fmt.Sprintf("%s%s", delim, str))
			delim = delimiter
		}
		io.WriteString(out, "\n")
	}
	return rs.Err()
}

// doubleQuoteForCSV follows the escaping rules from
// https://tools.ietf.org/html/rfc4180. In particular, values containing
// newlines, double quotes, and the delimiter must be enclosed in double
// quotes.
func doubleQuoteForCSV(str, delimiter string) string {
	doubleQuote := strings.Index(str, delimiter) != -1 || strings.Index(str, "\n") != -1
	if strings.Index(str, "\"") != -1 {
		str = strings.Replace(str, "\"", "\"\"", -1)
		doubleQuote = true
	}
	if doubleQuote {
		str = "\"" + str + "\""
	}
	return str
}

// WriteJson formats the result as a JSON array of arrays (rows) of values.
func WriteJson(out io.Writer, columnNames []string, rs nosql.ResultStream) error {
	io.WriteString(out, "[")
	jsonColNames := make([][]byte, len(columnNames))
	for i, cName := range columnNames {
		jsonCName, err := json.Marshal(cName)
		if err != nil {
			panic(fmt.Sprintf("JSON marshalling failed for column name: %v", err))
		}
		jsonColNames[i] = jsonCName
	}
	bOpen := "{"
	for rs.Advance() {
		io.WriteString(out, bOpen)
		linestart := "\n  "
		for i, column := range rs.Result() {
			str := toJson(column)
			io.WriteString(out, fmt.Sprintf("%s%s: %s", linestart, jsonColNames[i], str))
			linestart = ",\n  "
		}
		io.WriteString(out, "\n}")
		bOpen = ", {"
	}
	io.WriteString(out, "]\n")
	return rs.Err()
}

// Converts VDL value to readable yet parseable string representation.
// If nested is not set, strings outside composites are left unquoted.
// TODO(ivanpi): Handle cycles and improve non-tree DAG handling.
func toString(val *vdl.Value, nested bool) string {
	switch val.Type() {
	case vdl.TypeOf(vtime.Time{}), vdl.TypeOf(vtime.Duration{}):
		s, err := toStringNative(val)
		if err != nil {
			panic(fmt.Sprintf("toStringNative failed for builtin time type: %v", err))
		}
		if nested {
			s = strconv.Quote(s)
		}
		return s
	default:
		// fall through to Kind switch
	}
	switch val.Kind() {
	case vdl.Bool:
		return fmt.Sprint(val.Bool())
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return fmt.Sprint(val.Uint())
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		return fmt.Sprint(val.Int())
	case vdl.Float32, vdl.Float64:
		return fmt.Sprint(val.Float())
	case vdl.Complex64, vdl.Complex128:
		c := val.Complex()
		return fmt.Sprintf("%v+%vi", real(c), imag(c))
	case vdl.String:
		s := val.RawString()
		if nested {
			s = strconv.Quote(s)
		}
		return s
	case vdl.Enum:
		return val.EnumLabel()
	case vdl.Array, vdl.List:
		return listToString("[", ", ", "]", val.Len(), func(i int) string {
			return toString(val.Index(i), true)
		})
	case vdl.Any, vdl.Optional:
		if val.IsNil() {
			if nested {
				return "nil"
			}
			// TODO(ivanpi): Blank is better for CSV, but <nil> might be better for table and TSV.
			return ""
		}
		return toString(val.Elem(), nested)
	case vdl.Struct:
		return listToString("{", ", ", "}", val.Type().NumField(), func(i int) string {
			field := toString(val.StructField(i), true)
			return fmt.Sprintf("%s: %s", val.Type().Field(i).Name, field)
		})
	case vdl.Union:
		ui, uv := val.UnionField()
		field := toString(uv, true)
		return fmt.Sprintf("%s: %s", val.Type().Field(ui).Name, field)
	case vdl.Set:
		// TODO(ivanpi): vdl.SortValuesAsString() used for predictable output ordering.
		// Use a more sensible sort for numbers etc.
		keys := vdl.SortValuesAsString(val.Keys())
		return listToString("{", ", ", "}", len(keys), func(i int) string {
			return toString(keys[i], true)
		})
	case vdl.Map:
		// TODO(ivanpi): vdl.SortValuesAsString() used for predictable output ordering.
		// Use a more sensible sort for numbers etc.
		keys := vdl.SortValuesAsString(val.Keys())
		return listToString("{", ", ", "}", len(keys), func(i int) string {
			k := toString(keys[i], true)
			v := toString(val.MapIndex(keys[i]), true)
			return fmt.Sprintf("%s: %s", k, v)
		})
	case vdl.TypeObject:
		return val.String()
	default:
		panic(fmt.Sprintf("unknown Kind %s", val.Kind()))
	}
}

// Converts a VDL value to string using the corresponding native type String()
// method.
func toStringNative(val *vdl.Value) (string, error) {
	var natVal interface{}
	if err := vdl.Convert(&natVal, val); err != nil {
		return "", fmt.Errorf("failed converting %s to native value: %v", val.Type().String(), err)
	}
	if _, ok := natVal.(*vdl.Value); ok {
		return "", fmt.Errorf("failed converting %s to native value: got vdl.Value", val.Type().String())
	}
	if strNatVal, ok := natVal.(fmt.Stringer); !ok {
		return "", fmt.Errorf("native value of %s doesn't implement String()", val.Type().String())
	} else {
		return strNatVal.String(), nil
	}
}

// Stringifies a sequence of n elements, where element i string representation
// is obtained using elemToString(i),
func listToString(begin, sep, end string, n int, elemToString func(i int) string) string {
	elems := make([]string, n)
	for i, _ := range elems {
		elems[i] = elemToString(i)
	}
	return begin + strings.Join(elems, sep) + end
}

// Converts VDL value to JSON representation.
func toJson(val *vdl.Value) string {
	jf := toJsonFriendly(val)
	jOut, err := json.Marshal(jf)
	if err != nil {
		panic(fmt.Sprintf("JSON marshalling failed: %v", err))
	}
	return string(jOut)
}

// Converts VDL value to Go type compatible with json.Marshal().
func toJsonFriendly(val *vdl.Value) interface{} {
	switch val.Type() {
	case vdl.TypeOf(vtime.Time{}), vdl.TypeOf(vtime.Duration{}):
		s, err := toStringNative(val)
		if err != nil {
			panic(fmt.Sprintf("toStringNative failed for builtin time type: %v", err))
		}
		return s
	default:
		// fall through to Kind switch
	}
	switch val.Kind() {
	case vdl.Bool:
		return val.Bool()
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return val.Uint()
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		return val.Int()
	case vdl.Float32, vdl.Float64:
		return val.Float()
	case vdl.Complex64, vdl.Complex128:
		// Go doesn't support marshalling complex values, we need to stringify.
		c := val.Complex()
		return fmt.Sprintf("%v+%vi", real(c), imag(c))
	case vdl.String:
		return val.RawString()
	case vdl.Enum:
		return val.EnumLabel()
	case vdl.Array, vdl.List:
		arr := make([]interface{}, val.Len())
		for i, _ := range arr {
			arr[i] = toJsonFriendly(val.Index(i))
		}
		return arr
	case vdl.Any, vdl.Optional:
		if val.IsNil() {
			return nil
		}
		return toJsonFriendly(val.Elem())
	case vdl.Struct:
		// TODO(ivanpi): Consider lowercasing field names.
		return toOrderedMap(val.Type().NumField(), func(i int) (string, interface{}) {
			return val.Type().Field(i).Name, toJsonFriendly(val.StructField(i))
		})
	case vdl.Union:
		// TODO(ivanpi): Consider lowercasing field name.
		ui, uv := val.UnionField()
		return toOrderedMap(1, func(_ int) (string, interface{}) {
			return val.Type().Field(ui).Name, toJsonFriendly(uv)
		})
	case vdl.Set:
		// TODO(ivanpi): vdl.SortValuesAsString() used for predictable output ordering.
		// Use a more sensible sort for numbers etc.
		keys := vdl.SortValuesAsString(val.Keys())
		return toOrderedMap(len(keys), func(i int) (string, interface{}) {
			return toString(keys[i], false), true
		})
	case vdl.Map:
		// TODO(ivanpi): vdl.SortValuesAsString() used for predictable output ordering.
		// Use a more sensible sort for numbers etc.
		keys := vdl.SortValuesAsString(val.Keys())
		return toOrderedMap(len(keys), func(i int) (string, interface{}) {
			return toString(keys[i], false), toJsonFriendly(val.MapIndex(keys[i]))
		})
	case vdl.TypeObject:
		return val.String()
	default:
		panic(fmt.Sprintf("unknown Kind %s", val.Kind()))
	}
}

// Serializes to JSON object, preserving key order.
// Native Go map will serialize to JSON object with sorted keys, which is
// unexpected behaviour for a struct.
type orderedMap []orderedMapElem

type orderedMapElem struct {
	Key string
	Val interface{}
}

var _ json.Marshaler = (*orderedMap)(nil)

// Builds an orderedMap with n elements, obtaining the key and value of element
// i using elemToKeyVal(i).
func toOrderedMap(n int, elemToKeyVal func(i int) (string, interface{})) orderedMap {
	om := make(orderedMap, n)
	for i, _ := range om {
		om[i].Key, om[i].Val = elemToKeyVal(i)
	}
	return om
}

// Serializes orderedMap to JSON object, preserving key order.
func (om orderedMap) MarshalJSON() (_ []byte, rerr error) {
	defer func() {
		if r := recover(); r != nil {
			rerr = fmt.Errorf("orderedMap: %v", r)
		}
	}()
	return []byte(listToString("{", ",", "}", len(om), func(i int) string {
		keyJson, err := json.Marshal(om[i].Key)
		if err != nil {
			panic(err)
		}
		valJson, err := json.Marshal(om[i].Val)
		if err != nil {
			panic(err)
		}
		return fmt.Sprintf("%s:%s", keyJson, valJson)
	})), nil
}
