// Copyright 2010 The Go 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 json

import (
	"os"
	"bytes"
	"reflect"
	"runtime"
	"sort"
	"strconv"
)

// Marshal returns the JSON encoding of v.
//
// Marshal traverses the value v recursively.
// If an encountered value implements the Marshaler interface,
// Marshal calls its MarshalJSON method to produce JSON.
//
// Otherwise, Marshal uses the following type-dependent default encodings:
//
// Boolean values encode as JSON booleans.
//
// Floating point and integer values encode as JSON numbers.
//
// String values encode as JSON strings, with each invalid UTF-8 sequence
// replaced by the encoding of the Unicode replacement character U+FFFD.
//
// Array and slice values encode as JSON arrays.
//
// Struct values encode as JSON objects.  Each struct field becomes
// a member of the object.  By default the object's key name is the
// struct field name converted to lower case.  If the struct field
// has a tag, that tag will be used as the name instead.
//
// Map values encode as JSON objects.
// The map's key type must be string; the object keys are used directly
// as map keys.
//
// Pointer values encode as the value pointed to.
// A nil pointer encodes as the null JSON object.
//
// Interface values encode as the value contained in the interface.
// A nil interface value encodes as the null JSON object.
//
// Channel, complex, and function values cannot be encoded in JSON.
// Attempting to encode such a value causes Marshal to return
// an InvalidTypeError.
//
// JSON cannot represent cyclic data structures and Marshal does not
// handle them.  Passing cyclic structures to Marshal will result in
// an infinite recursion.
//
func Marshal(v interface{}) ([]byte, os.Error) {
	e := &encodeState{}
	err := e.marshal(v)
	if err != nil {
		return nil, err
	}
	return e.Bytes(), nil
}

// MarshalIndent is like Marshal but applies Indent to format the output.
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, os.Error) {
	b, err := Marshal(v)
	if err != nil {
		return nil, err
	}
	var buf bytes.Buffer
	err = Indent(&buf, b, prefix, indent)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

// Marshaler is the interface implemented by objects that
// can marshal themselves into valid JSON.
type Marshaler interface {
	MarshalJSON() ([]byte, os.Error)
}

type UnsupportedTypeError struct {
	Type reflect.Type
}

func (e *UnsupportedTypeError) String() string {
	return "json: unsupported type: " + e.Type.String()
}

type MarshalerError struct {
	Type  reflect.Type
	Error os.Error
}

func (e *MarshalerError) String() string {
	return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Error.String()
}

type interfaceOrPtrValue interface {
	IsNil() bool
	Elem() reflect.Value
}

var hex = "0123456789abcdef"

// An encodeState encodes JSON into a bytes.Buffer.
type encodeState struct {
	bytes.Buffer // accumulated output
}

func (e *encodeState) marshal(v interface{}) (err os.Error) {
	defer func() {
		if r := recover(); r != nil {
			if _, ok := r.(runtime.Error); ok {
				panic(r)
			}
			err = r.(os.Error)
		}
	}()
	e.reflectValue(reflect.NewValue(v))
	return nil
}

func (e *encodeState) error(err os.Error) {
	panic(err)
}

func (e *encodeState) reflectValue(v reflect.Value) {
	if v == nil {
		e.WriteString("null")
		return
	}

	if j, ok := v.Interface().(Marshaler); ok {
		b, err := j.MarshalJSON()
		if err == nil {
			// copy JSON into buffer, checking validity.
			err = Compact(&e.Buffer, b)
		}
		if err != nil {
			e.error(&MarshalerError{v.Type(), err})
		}
		return
	}

	switch v := v.(type) {
	case *reflect.BoolValue:
		x := v.Get()
		if x {
			e.WriteString("true")
		} else {
			e.WriteString("false")
		}

	case *reflect.IntValue:
		e.WriteString(strconv.Itoa64(v.Get()))

	case *reflect.UintValue:
		e.WriteString(strconv.Uitoa64(v.Get()))

	case *reflect.FloatValue:
		e.WriteString(strconv.FtoaN(v.Get(), 'g', -1, int(v.Type().Size()*8)))

	case *reflect.StringValue:
		e.string(v.Get())

	case *reflect.StructValue:
		e.WriteByte('{')
		t := v.Type().(*reflect.StructType)
		n := v.NumField()
		for i := 0; i < n; i++ {
			if i > 0 {
				e.WriteByte(',')
			}
			f := t.Field(i)
			if f.Tag != "" {
				e.string(f.Tag)
			} else {
				e.string(f.Name)
			}
			e.WriteByte(':')
			e.reflectValue(v.Field(i))
		}
		e.WriteByte('}')

	case *reflect.MapValue:
		if _, ok := v.Type().(*reflect.MapType).Key().(*reflect.StringType); !ok {
			e.error(&UnsupportedTypeError{v.Type()})
		}
		if v.IsNil() {
			e.WriteString("null")
			break
		}
		e.WriteByte('{')
		var sv stringValues = v.Keys()
		sort.Sort(sv)
		for i, k := range sv {
			if i > 0 {
				e.WriteByte(',')
			}
			e.string(k.(*reflect.StringValue).Get())
			e.WriteByte(':')
			e.reflectValue(v.Elem(k))
		}
		e.WriteByte('}')

	case reflect.ArrayOrSliceValue:
		e.WriteByte('[')
		n := v.Len()
		for i := 0; i < n; i++ {
			if i > 0 {
				e.WriteByte(',')
			}
			e.reflectValue(v.Elem(i))
		}
		e.WriteByte(']')

	case interfaceOrPtrValue:
		if v.IsNil() {
			e.WriteString("null")
			return
		}
		e.reflectValue(v.Elem())

	default:
		e.error(&UnsupportedTypeError{v.Type()})
	}
	return
}

// stringValues is a slice of reflect.Value holding *reflect.StringValue.
// It implements the methods to sort by string.
type stringValues []reflect.Value

func (sv stringValues) Len() int           { return len(sv) }
func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
func (sv stringValues) get(i int) string   { return sv[i].(*reflect.StringValue).Get() }

func (e *encodeState) string(s string) {
	e.WriteByte('"')
	for _, c := range s {
		switch {
		case c < 0x20:
			e.WriteString(`\u00`)
			e.WriteByte(hex[c>>4])
			e.WriteByte(hex[c&0xF])
		case c == '\\' || c == '"':
			e.WriteByte('\\')
			fallthrough
		default:
			e.WriteRune(c)
		}
	}
	e.WriteByte('"')
}
