// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package json

import (
	"bytes"
	"encoding/json"
	"fmt"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/legacy/cue"
)

// Compact generates the JSON-encoded src with insignificant space characters
// elided.
func Compact(src []byte) (string, error) {
	dst := bytes.Buffer{}
	if err := json.Compact(&dst, src); err != nil {
		return "", err
	}
	return dst.String(), nil
}

// Indent creates an indented form of the JSON-encoded src.
// Each element in a JSON object or array begins on a new,
// indented line beginning with prefix followed by one or more
// copies of indent according to the indentation nesting.
// The data appended to dst does not begin with the prefix nor
// any indentation, to make it easier to embed inside other formatted JSON data.
// Although leading space characters (space, tab, carriage return, newline)
// at the beginning of src are dropped, trailing space characters
// at the end of src are preserved and copied to dst.
// For example, if src has no trailing spaces, neither will dst;
// if src ends in a trailing newline, so will dst.
func Indent(src []byte, prefix, indent string) (string, error) {
	dst := bytes.Buffer{}
	if err := json.Indent(&dst, src, prefix, indent); err != nil {
		return "", err
	}
	return dst.String(), nil
}

// HTMLEscape returns the JSON-encoded src with <, >, &, U+2028 and
// U+2029 characters inside string literals changed to \u003c, \u003e, \u0026,
// \u2028, \u2029 so that the JSON will be safe to embed inside HTML <script>
// tags. For historical reasons, web browsers don't honor standard HTML escaping
// within <script> tags, so an alternative JSON encoding must be used.
func HTMLEscape(src []byte) string {
	dst := &bytes.Buffer{}
	json.HTMLEscape(dst, src)
	return dst.String()
}

// Marshal returns the JSON encoding of v.
func Marshal(v cue.Value) (string, error) {
	b, err := json.Marshal(v)
	return string(b), err
}

// MarshalStream turns a list into a stream of JSON objects.
func MarshalStream(v cue.Value) (string, error) {
	// TODO: return an io.Reader and allow asynchronous processing.
	iter, err := v.List()
	if err != nil {
		return "", err
	}
	buf := &bytes.Buffer{}
	for iter.Next() {
		b, err := json.Marshal(iter.Value())
		if err != nil {
			return "", err
		}
		buf.Write(b)
		buf.WriteByte('\n')
	}
	return buf.String(), nil
}

// Unmarshal parses the JSON-encoded data.
func Unmarshal(b []byte) (ast.Expr, error) {
	if !json.Valid(b) {
		return nil, fmt.Errorf("json: invalid JSON")
	}
	expr, err := parser.ParseExpr("json", b)
	if err != nil {
		// NOTE: should never happen.
		return nil, fmt.Errorf("json: could not parse JSON: %v", err)
	}
	return expr, nil
}

// Validate validates JSON and confirms it matches the constraints
// specified by v.
func Validate(b []byte, v cue.Value) (bool, error) {
	if !json.Valid(b) {
		return false, fmt.Errorf("json: invalid JSON")
	}
	r := internal.GetRuntimeNew(v).(*cue.Runtime)
	inst, err := r.Compile("json.Validate", b)
	if err != nil {
		return false, err
	}

	v = v.Unify(inst.Value())
	if v.Err() != nil {
		return false, v.Err()
	}
	return true, nil
}
