// 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 cue

import (
	"bytes"
	"testing"

	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
)

func TestCompile(t *testing.T) {
	testCases := []struct {
		in  string
		out string
	}{{
		in: `{
		  foo: 1,
		}`,
		out: "<0>{}", // emitted value, but no top-level fields
	}, {
		in: `
		foo: 1
		`,
		out: "<0>{foo: 1}",
	}, {
		in: `
		a: true
		b: 2K
		c: 4_5
		d: "abc"
		e: 3e2 // 3h1m2ss
		`,
		out: "<0>{a: true, b: 2000, c: 45, d: \"abc\", e: 3e+2}",
	}, {
		in: `
		a: null
		b: true
		c: false
		`,
		out: "<0>{a: null, b: true, c: false}",
	}, {
		in: `
		a: <1
		b: >= 0 & <= 10
		c: != null
		d: >100
		`,
		out: `<0>{a: <1, b: (>=0 & <=10), c: !=null, d: >100}`,
	}, {
		in: "" +
			`a: "\(4)",
			b: "one \(a) two \(  a + c  )",
			c: "one"`,
		out: `<0>{a: ""+4+"", b: "one "+<0>.a+" two "+(<0>.a + <0>.c)+"", c: "one"}`,
	}, {
		in: "" +
			`a: """
				multi
				""",
			b: '''
				hello world
				goodbye globe
				welcome back planet
				'''`,
		out: `<0>{a: "multi", b: 'hello world\ngoodbye globe\nwelcome back planet'}`,
	}, {
		in: "" +
			`a: """
				multi \(4)
				""",
			b: """
				hello \("world")
				goodbye \("globe")
				welcome back \("planet")
				"""`,
		out: `<0>{a: "multi "+4+"", b: "hello "+"world"+"\ngoodbye "+"globe"+"\nwelcome back "+"planet"+""}`,
	}, {
		in: `
		a: _
		b: int
		c: float
		d: bool
		e: duration
		f: string
		`,
		out: "<0>{a: _, b: int, c: float, d: bool, e: duration, f: string}",
	}, {
		in: `
		a: null
		b: true
		c: false
		`,
		out: "<0>{a: null, b: true, c: false}",
	}, {
		in: `
		null: null
		true: true
		false: false
		`,
		out: "<0>{null: null, true: true, false: false}",
	}, {
		in: `
		a: 1 + 2
		b: -2 - 3
		c: !d
		d: true
		`,
		out: "<0>{a: (1 + 2), b: (-2 - 3), c: !<0>.d, d: true}",
	}, {
		in: `
			l0: 3*[int]
			l0: [1, 2, 3]
			l1: <=5*[string]
			l1: ["a", "b"]
			l2: (<=5)*[{ a: int }]
			l2: [{a: 1}, {a: 2, b: 3}]
			l3: (<=10)*[int]
			l3: [1, 2, 3, ...]
			l4: [1, 2, ...]
			l4: [...int]
			l5: [1, ...int]

			s1: ((<=6)*[int])[2:3]
			s2: [0,2,3][1:2]

			e0: (>=2 & <=5)*[{}]
			e0: [{}]
			`,
		out: `<0>{l0: ((3 * [int]) & [1,2,3]), l1: ((<=5 * [string]) & ["a","b"]), l2: ((<=5 * [<1>{a: int}]) & [<2>{a: 1},<3>{a: 2, b: 3}]), l3: ((<=10 * [int]) & [1,2,3, ...]), l4: ([1,2, ...] & [, ...int]), l5: [1, ...int], s1: (<=6 * [int])[2:3], s2: [0,2,3][1:2], e0: (((>=2 & <=5) * [<4>{}]) & [<5>{}])}`,
	}, {
		in: `
		a: 5 | "a" | true
		aa: 5 | *"a" | true
		b c: {
			cc: { ccc: 3 }
		}
		d: true
		`,
		out: "<0>{a: (5 | \"a\" | true), aa: (5 | *\"a\" | true), b: <1>{c: <2>{cc: <3>{ccc: 3}}}, d: true}",
	}, {
		in: `
		a a: { b: a } // referencing ancestor nodes is legal.
		a b: a.a      // do lookup before merging of nodes
		b: a.a        // different node as a.a.b, as first node counts
		c: a          // same node as b, as first node counts
		d: a["a"]
		`,
		out: `<0>{a: (<1>{a: <2>{b: <2>}} & <3>{b: <3>.a}), b: <0>.a.a, c: <0>.a, d: <0>.a["a"]}`,
	}, {
		// bunch of aliases
		in: `
		a1 = a2
		a2 = 5
		b: a1
		a3 = d
		c: {
			d: {
				r: a3
			}
			r: a3
		}
		d: { e: 4 }
		`,
		out: `<0>{b: 5, c: <1>{d: <2>{r: <0>.d}, r: <0>.d}, d: <3>{e: 4}}`,
	}, {
		// aliases with errors
		in: `
		e1 = 1
		e1 = 2
		e1v: e1
		e2: "a"
		e2 = "a"
		`,
		out: "cannot have two aliases with the same name in the same scope:\n" +
			"    test:3:3\n" +
			"cannot have alias and non-alias with the same name:\n" +
			"    test:6:3\n" +
			"<0>{}",
	}, {
		in: `
		a = b
		b: {
			c: a // reference to own root.
		}
		`,
		out: `<0>{b: <1>{c: <0>.b}}`,
	}, {
		in: `
		a: {
			<name>: { n: name }
			k: 1
		}
		b: {
			<x>: { x: 0, y: 1 }
			v: {}
		}
		`,
		out: `<0>{a: <1>{<>: <2>(name: string)-><3>{n: <2>.name}, k: 1}, b: <4>{<>: <5>(x: string)-><6>{x: 0, y: 1}, v: <7>{}}}`,
	}, {
		in: `
		a: { "\(k)": v for k, v in b if b.a < k }
		b: {
			a: 1
			b: 2
			c: 3
		}
		`,
		out: `<0>{a: <1>{ <2>for k, v in <0>.b if (<0>.b.a < <2>.k) yield (""+<2>.k+""): <2>.v}, b: <3>{a: 1, b: 2, c: 3}}`,
	}, {
		in: `
			a: { "\(v)": v for k, v in b }
			b: { a: "aa", b: "bb", c: "cc" }
			`,
		out: `<0>{a: <1>{ <2>for k, v in <0>.b yield (""+<2>.v+""): <2>.v}, b: <3>{a: "aa", b: "bb", c: "cc"}}`,
	}, {
		in: `
			a: [ v for _, v in b ]
			b: { a: 1, b: 2, c: 3 }
			`,
		out: `<0>{a: [ <1>for _, v in <0>.b yield (*nil*): <1>.v ], b: <2>{a: 1, b: 2, c: 3}}`,
	}, {
		in: `
			a: >=1 & <=2
			b: >=1 & >=2 & <=3
			c: >="a" & <"b"
			d: >(2+3) & <(4+5)
			`,
		out: `<0>{a: (>=1 & <=2), b: ((>=1 & >=2) & <=3), c: (>="a" & <"b"), d: (>(2 + 3) & <(4 + 5))}`,
	}, {
		in: `
			a: *1,
			b: **1 | 2
		`,
		out: `<0>{a: _|_(preference mark not allowed at this position), ` +
			`b: (*_|_(preference mark not allowed at this position) | 2)}`,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			ctx, root, errs := compileFileWithErrors(t, tc.in)
			buf := &bytes.Buffer{}
			if len(errs) > 0 {
				errors.Print(buf, errs)
			}
			buf.WriteString(debugStr(ctx, root))
			got := buf.String()
			if got != tc.out {
				t.Errorf("output differs:\ngot  %q\nwant %q", got, tc.out)
			}
		})
	}
}

func TestEmit(t *testing.T) {
	testCases := []struct {
		in  string
		out string
		rw  rewriteMode
	}{{
		in: `"\(hello), \(world)!"` + `
		hello: "Hello"
		world: "World"
		`,
		out: `""+<0>.hello+", "+<0>.world+"!"`,
		rw:  evalRaw,
	}, {
		in: `"\(hello), \(world)!"` + `
		hello: "Hello"
		world: "World"
		`,
		out: `"Hello, World!"`,
		rw:  evalPartial,
	}, {
		// Ambiguous disjunction must cary over to emit value.
		in: `baz

		baz: {
			a: 8000 | 7080
			a: 7080 | int
		}`,
		out: `<0>{a: _|_((8000 | 7080):more than one element remaining (8000 and 7080))}`,
		rw:  evalFull,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			ctx, root := compileFile(t, tc.in)
			v := testResolve(ctx, root.emit, tc.rw)
			if got := debugStr(ctx, v); got != tc.out {
				t.Errorf("output differs:\ngot  %q\nwant %q", got, tc.out)
			}
		})
	}
}

func TestEval(t *testing.T) {
	testCases := []struct {
		in   string
		expr string
		out  string
	}{{
		in: `
			hello: "Hello"
			world: "World"
			`,
		expr: `"\(hello), \(world)!"`,
		out:  `"Hello, World!"`,
	}, {
		in: `
			a: { b: 2, c: 3 }
			z: 1
			`,
		expr: `a.b + a.c + z`,
		out:  `6`,
	}, {
		in: `
			a: { b: 2, c: 3 }
			`,
		expr: `{ d: a.b + a.c }`,
		out:  `<0>{d: 5}`,
	}, {
		in: `
			a: "Hello World!"
			`,
		expr: `strings.ToUpper(a)`,
		out:  `"HELLO WORLD!"`,
	}, {
		in: `
			a: 0x8
			b: 0x1`,
		expr: `bits.Or(a, b)`, // package shorthand
		out:  `9`,
	}, {
		in: `
			a: 0x8
			b: 0x1`,
		expr: `math.Or(a, b)`,
		out:  `_|_(<0>.Or:undefined field "Or")`,
	}, {
		in:   `a: 0x8`,
		expr: `mathematics.Abs(a)`,
		out:  `_|_(reference "mathematics" not found)`,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			ctx, inst, errs := compileInstance(t, tc.in)
			if errs != nil {
				t.Fatal(errs)
			}
			expr, err := parser.ParseExpr(token.NewFileSet(), "<test>", tc.expr)
			if err != nil {
				t.Fatal(err)
			}
			evaluated := inst.evalExpr(ctx, expr)
			v := testResolve(ctx, evaluated, evalFull)
			if got := debugStr(ctx, v); got != tc.out {
				t.Errorf("output differs:\ngot  %q\nwant %q", got, tc.out)
			}
		})
	}
}
