// 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"
)

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, nil)
			}
			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("<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)
			}
		})
	}
}
