// 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";
	"json";
	"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
}

// 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 errindx int;
	var j Json;
	b := new(_JsonBuilder);
	b.ptr = &j;
	ok, errindx, 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.
