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

// Generic representation of JSON objects.

package json

import (
	"container/vector";
	"fmt";
	"math";
	"strconv";
	"strings";
)

// Integers identifying the data type in the Json interface.
const (
	StringKind	= iota;
	NumberKind;
	MapKind;	// JSON term is "Object", but in Go, it's a map
	ArrayKind;
	BoolKind;
	NullKind;
)

// The Json interface is implemented by all JSON objects.
type Json interface {
	Kind() int;		// StringKind, NumberKind, etc.
	String() string;	// a string form (any kind)
	Number() float64;	// numeric form (NumberKind)
	Bool() bool;		// boolean (BoolKind)
	Get(s string) Json;	// field lookup (MapKind)
	Elem(i int) Json;	// element lookup (ArrayKind)
	Len() int;		// length (ArrayKind, MapKind)
}

// JsonToString returns the textual JSON syntax representation
// for the JSON object j.
//
// JsonToString differs from j.String() in the handling
// of string objects.  If j represents the string abc,
// j.String() == `abc`, but JsonToString(j) == `"abc"`.
func JsonToString(j Json) string {
	if j == nil {
		return "null";
	}
	if j.Kind() == StringKind {
		return Quote(j.String());
	}
	return j.String();
}

type _Null struct{}

// Null is the JSON object representing the null data object.
var Null Json = &_Null{}

func (*_Null) Kind() int {
	return NullKind;
}
func (*_Null) String() string {
	return "null";
}
func (*_Null) Number() float64 {
	return 0;
}
func (*_Null) Bool() bool {
	return false;
}
func (*_Null) Get(s string) Json {
	return Null;
}
func (*_Null) Elem(int) Json {
	return Null;
}
func (*_Null) Len() int {
	return 0;
}

type _String struct {
	s	string;
	_Null;
}

func (j *_String) Kind() int {
	return StringKind;
}
func (j *_String) String() string {
	return j.s;
}

type _Number struct {
	f	float64;
	_Null;
}

func (j *_Number) Kind() int {
	return NumberKind;
}
func (j *_Number) Number() float64 {
	return j.f;
}
func (j *_Number) String() string {
	if math.Floor(j.f) == j.f {
		return fmt.Sprintf("%.0f", j.f);
	}
	return fmt.Sprintf("%g", j.f);
}

type _Array struct {
	a	*vector.Vector;
	_Null;
}

func (j *_Array) Kind() int {
	return ArrayKind;
}
func (j *_Array) Len() int {
	return j.a.Len();
}
func (j *_Array) Elem(i int) Json {
	if i < 0 || i >= j.a.Len() {
		return Null;
	}
	return j.a.At(i).(Json);
}
func (j *_Array) String() string {
	s := "[";
	for i := 0; i < j.a.Len(); i++ {
		if i > 0 {
			s += ",";
		}
		s += JsonToString(j.a.At(i).(Json));
	}
	s += "]";
	return s;
}

type _Bool struct {
	b	bool;
	_Null;
}

func (j *_Bool) Kind() int {
	return BoolKind;
}
func (j *_Bool) Bool() bool {
	return j.b;
}
func (j *_Bool) String() string {
	if j.b {
		return "true";
	}
	return "false";
}

type _Map struct {
	m	map[string]Json;
	_Null;
}

func (j *_Map) Kind() int {
	return MapKind;
}
func (j *_Map) Len() int {
	return len(j.m);
}
func (j *_Map) Get(s string) Json {
	if j.m == nil {
		return Null;
	}
	v, ok := j.m[s];
	if !ok {
		return Null;
	}
	return v;
}
func (j *_Map) String() string {
	s := "{";
	first := true;
	for k, v := range j.m {
		if first {
			first = false;
		} else {
			s += ",";
		}
		s += Quote(k);
		s += ":";
		s += JsonToString(v);
	}
	s += "}";
	return s;
}

// Walk evaluates path relative to the JSON object j.
// Path is taken as a sequence of slash-separated field names
// or numbers that can be used to index into JSON map and
// array objects.
//
// For example, if j is the JSON object for
// {"abc": [true, false]}, then Walk(j, "abc/1") returns the
// JSON object for true.
func Walk(j Json, path string) Json {
	for len(path) > 0 {
		var elem string;
		if i := strings.Index(path, "/"); i >= 0 {
			elem = path[0:i];
			path = path[i+1 : len(path)];
		} else {
			elem = path;
			path = "";
		}
		switch j.Kind() {
		case ArrayKind:
			indx, err := strconv.Atoi(elem);
			if err != nil {
				return Null;
			}
			j = j.Elem(indx);
		case MapKind:
			j = j.Get(elem);
		default:
			return Null;
		}
	}
	return j;
}

// Equal returns whether a and b are indistinguishable JSON objects.
func Equal(a, b Json) bool {
	switch {
	case a == nil && b == nil:
		return true;
	case a == nil || b == nil:
		return false;
	case a.Kind() != b.Kind():
		return false;
	}

	switch a.Kind() {
	case NullKind:
		return true;
	case StringKind:
		return a.String() == b.String();
	case NumberKind:
		return a.Number() == b.Number();
	case BoolKind:
		return a.Bool() == b.Bool();
	case ArrayKind:
		if a.Len() != b.Len() {
			return false;
		}
		for i := 0; i < a.Len(); i++ {
			if !Equal(a.Elem(i), b.Elem(i)) {
				return false;
			}
		}
		return true;
	case MapKind:
		m := a.(*_Map).m;
		if len(m) != len(b.(*_Map).m) {
			return false;
		}
		for k, v := range m {
			if !Equal(v, b.Get(k)) {
				return false;
			}
		}
		return true;
	}

	// invalid kind
	return false;
}


// Parse builder for JSON objects.

type _JsonBuilder struct {
	// either writing to *ptr
	ptr	*Json;

	// or to a[i] (can't set ptr = &a[i])
	a	*vector.Vector;
	i	int;

	// or to m[k] (can't set ptr = &m[k])
	m	map[string]Json;
	k	string;
}

func (b *_JsonBuilder) Put(j Json) {
	switch {
	case b.ptr != nil:
		*b.ptr = j;
	case b.a != nil:
		b.a.Set(b.i, j);
	case b.m != nil:
		b.m[b.k] = j;
	}
}

func (b *_JsonBuilder) Get() Json {
	switch {
	case b.ptr != nil:
		return *b.ptr;
	case b.a != nil:
		return b.a.At(b.i).(Json);
	case b.m != nil:
		return b.m[b.k];
	}
	return nil;
}

func (b *_JsonBuilder) Float64(f float64) {
	b.Put(&_Number{f, _Null{}});
}

func (b *_JsonBuilder) Int64(i int64) {
	b.Float64(float64(i));
}

func (b *_JsonBuilder) Uint64(i uint64) {
	b.Float64(float64(i));
}

func (b *_JsonBuilder) Bool(tf bool) {
	b.Put(&_Bool{tf, _Null{}});
}

func (b *_JsonBuilder) Null() {
	b.Put(Null);
}

func (b *_JsonBuilder) String(s string) {
	b.Put(&_String{s, _Null{}});
}


func (b *_JsonBuilder) Array() {
	b.Put(&_Array{vector.New(0), _Null{}});
}

func (b *_JsonBuilder) Map() {
	b.Put(&_Map{make(map[string]Json), _Null{}});
}

func (b *_JsonBuilder) Elem(i int) Builder {
	bb := new(_JsonBuilder);
	bb.a = b.Get().(*_Array).a;
	bb.i = i;
	for i >= bb.a.Len() {
		bb.a.Push(Null);
	}
	return bb;
}

func (b *_JsonBuilder) Key(k string) Builder {
	bb := new(_JsonBuilder);
	bb.m = b.Get().(*_Map).m;
	bb.k = k;
	bb.m[k] = Null;
	return bb;
}

func (b *_JsonBuilder) Flush() {
}

// StringToJson parses the string s as a JSON-syntax string
// and returns the generic JSON object representation.
// On success, StringToJson returns with ok set to true and errtok empty.
// If StringToJson encounters a syntax error, it returns with
// ok set to false and errtok set to a fragment of the offending syntax.
func StringToJson(s string) (json Json, ok bool, errtok string) {
	var j Json;
	b := new(_JsonBuilder);
	b.ptr = &j;
	ok, _, errtok = Parse(s, b);
	if !ok {
		return nil, false, errtok;
	}
	return j, true, "";
}

// BUG(rsc): StringToJson should return an os.Error instead of a bool.
