// Package jsonutil provides JSON serialization of AWS requests and responses.
package jsonutil

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"math"
	"reflect"
	"sort"
	"strconv"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/private/protocol"
)

var timeType = reflect.ValueOf(time.Time{}).Type()
var byteSliceType = reflect.ValueOf([]byte{}).Type()

// BuildJSON builds a JSON string for a given object v.
func BuildJSON(v interface{}) ([]byte, error) {
	var buf bytes.Buffer

	err := buildAny(reflect.ValueOf(v), &buf, "")
	return buf.Bytes(), err
}

func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
	origVal := value
	value = reflect.Indirect(value)
	if !value.IsValid() {
		return nil
	}

	vtype := value.Type()

	t := tag.Get("type")
	if t == "" {
		switch vtype.Kind() {
		case reflect.Struct:
			// also it can't be a time object
			if value.Type() != timeType {
				t = "structure"
			}
		case reflect.Slice:
			// also it can't be a byte slice
			if _, ok := value.Interface().([]byte); !ok {
				t = "list"
			}
		case reflect.Map:
			// cannot be a JSONValue map
			if _, ok := value.Interface().(aws.JSONValue); !ok {
				t = "map"
			}
		}
	}

	switch t {
	case "structure":
		if field, ok := vtype.FieldByName("_"); ok {
			tag = field.Tag
		}
		return buildStruct(value, buf, tag)
	case "list":
		return buildList(value, buf, tag)
	case "map":
		return buildMap(value, buf, tag)
	default:
		return buildScalar(origVal, buf, tag)
	}
}

func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
	if !value.IsValid() {
		return nil
	}

	// unwrap payloads
	if payload := tag.Get("payload"); payload != "" {
		field, _ := value.Type().FieldByName(payload)
		tag = field.Tag
		value = elemOf(value.FieldByName(payload))

		if !value.IsValid() {
			return nil
		}
	}

	buf.WriteByte('{')

	t := value.Type()
	first := true
	for i := 0; i < t.NumField(); i++ {
		member := value.Field(i)

		// This allocates the most memory.
		// Additionally, we cannot skip nil fields due to
		// idempotency auto filling.
		field := t.Field(i)

		if field.PkgPath != "" {
			continue // ignore unexported fields
		}
		if field.Tag.Get("json") == "-" {
			continue
		}
		if field.Tag.Get("location") != "" {
			continue // ignore non-body elements
		}
		if field.Tag.Get("ignore") != "" {
			continue
		}

		if protocol.CanSetIdempotencyToken(member, field) {
			token := protocol.GetIdempotencyToken()
			member = reflect.ValueOf(&token)
		}

		if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() {
			continue // ignore unset fields
		}

		if first {
			first = false
		} else {
			buf.WriteByte(',')
		}

		// figure out what this field is called
		name := field.Name
		if locName := field.Tag.Get("locationName"); locName != "" {
			name = locName
		}

		writeString(name, buf)
		buf.WriteString(`:`)

		err := buildAny(member, buf, field.Tag)
		if err != nil {
			return err
		}

	}

	buf.WriteString("}")

	return nil
}

func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
	buf.WriteString("[")

	for i := 0; i < value.Len(); i++ {
		buildAny(value.Index(i), buf, "")

		if i < value.Len()-1 {
			buf.WriteString(",")
		}
	}

	buf.WriteString("]")

	return nil
}

type sortedValues []reflect.Value

func (sv sortedValues) Len() int           { return len(sv) }
func (sv sortedValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() }

func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
	buf.WriteString("{")

	sv := sortedValues(value.MapKeys())
	sort.Sort(sv)

	for i, k := range sv {
		if i > 0 {
			buf.WriteByte(',')
		}

		writeString(k.String(), buf)
		buf.WriteString(`:`)

		buildAny(value.MapIndex(k), buf, "")
	}

	buf.WriteString("}")

	return nil
}

func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
	// prevents allocation on the heap.
	scratch := [64]byte{}
	switch value := reflect.Indirect(v); value.Kind() {
	case reflect.String:
		writeString(value.String(), buf)
	case reflect.Bool:
		if value.Bool() {
			buf.WriteString("true")
		} else {
			buf.WriteString("false")
		}
	case reflect.Int64:
		buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10))
	case reflect.Float64:
		f := value.Float()
		if math.IsInf(f, 0) || math.IsNaN(f) {
			return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)}
		}
		buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64))
	default:
		switch converted := value.Interface().(type) {
		case time.Time:
			format := tag.Get("timestampFormat")
			if len(format) == 0 {
				format = protocol.UnixTimeFormatName
			}

			ts := protocol.FormatTime(format, converted)
			if format != protocol.UnixTimeFormatName {
				ts = `"` + ts + `"`
			}

			buf.WriteString(ts)
		case []byte:
			if !value.IsNil() {
				buf.WriteByte('"')
				if len(converted) < 1024 {
					// for small buffers, using Encode directly is much faster.
					dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted)))
					base64.StdEncoding.Encode(dst, converted)
					buf.Write(dst)
				} else {
					// for large buffers, avoid unnecessary extra temporary
					// buffer space.
					enc := base64.NewEncoder(base64.StdEncoding, buf)
					enc.Write(converted)
					enc.Close()
				}
				buf.WriteByte('"')
			}
		case aws.JSONValue:
			str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape)
			if err != nil {
				return fmt.Errorf("unable to encode JSONValue, %v", err)
			}
			buf.WriteString(str)
		default:
			return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type())
		}
	}
	return nil
}

var hex = "0123456789abcdef"

func writeString(s string, buf *bytes.Buffer) {
	buf.WriteByte('"')
	for i := 0; i < len(s); i++ {
		if s[i] == '"' {
			buf.WriteString(`\"`)
		} else if s[i] == '\\' {
			buf.WriteString(`\\`)
		} else if s[i] == '\b' {
			buf.WriteString(`\b`)
		} else if s[i] == '\f' {
			buf.WriteString(`\f`)
		} else if s[i] == '\r' {
			buf.WriteString(`\r`)
		} else if s[i] == '\t' {
			buf.WriteString(`\t`)
		} else if s[i] == '\n' {
			buf.WriteString(`\n`)
		} else if s[i] < 32 {
			buf.WriteString("\\u00")
			buf.WriteByte(hex[s[i]>>4])
			buf.WriteByte(hex[s[i]&0xF])
		} else {
			buf.WriteByte(s[i])
		}
	}
	buf.WriteByte('"')
}

// Returns the reflection element of a value, if it is a pointer.
func elemOf(value reflect.Value) reflect.Value {
	for value.Kind() == reflect.Ptr {
		value = value.Elem()
	}
	return value
}
