// Copyright 2019 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 (
	"fmt"
	"reflect"
	"strings"
	"testing"

	"cuelang.org/go/cue/ast"
)

func TestAttributeBody(t *testing.T) {
	testdata := []struct {
		in, out string
		err     string
	}{{
		in:  "",
		out: "[{ 0}]",
	}, {
		in:  "bb",
		out: "[{bb 0}]",
	}, {
		in:  "a,",
		out: "[{a 0} { 0}]",
	}, {
		in:  `"a",`,
		out: "[{a 0} { 0}]",
	}, {
		in:  "a,b",
		out: "[{a 0} {b 0}]",
	}, {
		in:  `foo,"bar",#"baz"#`,
		out: "[{foo 0} {bar 0} {baz 0}]",
	}, {
		in:  `bar=str`,
		out: "[{bar=str 3}]",
	}, {
		in:  `bar="str"`,
		out: "[{bar=str 3}]",
	}, {
		in:  `foo.bar="str"`,
		out: "[{foo.bar=str 7}]",
	}, {
		in:  `bar=,baz=`,
		out: "[{bar= 3} {baz= 3}]",
	}, {
		in:  `foo=1,bar="str",baz=free form`,
		out: "[{foo=1 3} {bar=str 3} {baz=free form 3}]",
	}, {
		in: `"""
		"""`,
		out: "[{ 0}]",
	}, {
		in: `#'''
			\#x20
			'''#`,
		out: "[{  0}]",
	}, {
		in:  "'' ,b",
		err: "invalid attribute",
	}, {
		in:  "' ,b",
		err: "not terminated",
	}, {
		in:  `"\ "`,
		err: "invalid attribute",
	}, {
		in:  `# `,
		err: "invalid attribute",
	}}
	for _, tc := range testdata {
		t.Run(tc.in, func(t *testing.T) {
			pa := &parsedAttr{}
			err := parseAttrBody(&context{}, baseValue{}, tc.in, pa)

			if tc.err != "" {
				if !strings.Contains(debugStr(&context{}, err), tc.err) {
					t.Errorf("error was %v; want %v", err, tc.err)
				}
				return
			}
			if err != nil {
				t.Fatal(err)
			}

			if got := fmt.Sprint(pa.fields); got != tc.out {
				t.Errorf("got %v; want %v", got, tc.out)
			}
		})
	}
}

func TestCreateAttrs(t *testing.T) {
	testdata := []struct {
		// space-separated lists of attributes
		in, out string
		err     string
	}{{
		in:  "@foo()",
		out: "foo:",
	}, {
		in:  "@b(bb) @aaa(aa,)",
		out: "aaa:aa, b:bb",
	}, {
		in:  "@b(a,",
		err: "invalid attribute",
	}, {
		in:  "@b(foo) @b(foo)",
		err: "attributes",
	}, {
		in:  "@b('' ,b)",
		err: "invalid attribute",
	}, {
		in:  `@foo(,"bar")`,
		out: `foo:,"bar"`,
	}, {
		in:  `@foo("bar",1)`,
		out: `foo:"bar",1`,
	}, {
		in:  `@foo("bar")`,
		out: `foo:"bar"`,
	}, {
		in:  `@foo(,"bar",1)`,
		out: `foo:,"bar",1`,
	}}
	for _, tc := range testdata {
		t.Run(tc.in, func(t *testing.T) {
			a := []*ast.Attribute{}
			for _, s := range strings.Split(tc.in, " ") {
				a = append(a, &ast.Attribute{Text: s})
			}
			attrs, err := createAttrs(&context{}, baseValue{}, a)

			if tc.err != "" {
				if err == nil || !strings.Contains(debugStr(&context{}, err), tc.err) {
					t.Errorf("error was %v; want %v", err, tc.err)
				}
				return
			}
			if err != nil {
				t.Fatal(err)
			}
			sa := []string{}
			for _, a := range attrs.attr {
				sa = append(sa, a.key()+":"+a.body())
			}
			if got := strings.Join(sa, " "); got != tc.out {
				t.Errorf("got %v; want %v", got, tc.out)
			}
		})
	}
}

func TestUnifyAttrs(t *testing.T) {
	parse := func(s string) *attributes {
		a := []*ast.Attribute{}
		for _, s := range strings.Split(s, " ") {
			a = append(a, &ast.Attribute{Text: s})
		}
		attrs, _ := createAttrs(&context{}, baseValue{}, a)
		return attrs
	}
	foo := parse("@foo()")

	testdata := []struct {
		// space-separated lists of attributes
		a, b, out *attributes
		err       string
	}{{
		a:   nil,
		b:   nil,
		out: nil,
	}, {
		a:   nil,
		b:   foo,
		out: foo,
	}, {
		a:   foo,
		b:   nil,
		out: foo,
	}, {
		a:   foo,
		b:   foo,
		out: foo,
	}, {
		a:   foo,
		b:   parse("@bar()"),
		out: parse("@bar() @foo()"),
	}, {
		a:   foo,
		b:   parse("@bar() @foo()"),
		out: parse("@bar() @foo()"),
	}, {
		a:   parse("@bar() @foo()"),
		b:   parse("@foo() @bar()"),
		out: parse("@bar() @foo()"),
	}, {
		a:   parse("@bar() @foo()"),
		b:   parse("@foo() @baz()"),
		out: parse("@bar() @baz() @foo()"),
	}, {
		a:   parse("@foo(ab)"),
		b:   parse("@foo(cd)"),
		err: `conflicting attributes for key "foo"`,
	}}
	for _, tc := range testdata {
		t.Run("", func(t *testing.T) {
			attrs, err := unifyAttrs(&context{}, baseValue{}, tc.a, tc.b)
			if tc.err != "" {
				if !strings.Contains(debugStr(&context{}, err), tc.err) {
					t.Errorf("error was %v; want %v", err, tc.err)
				}
				return
			}
			if err != nil {
				t.Fatal(err)
			}
			if !reflect.DeepEqual(attrs, tc.out) {
				t.Errorf("\ngot:  %v;\nwant: %v", attrs, tc.out)
			}
		})
	}
}
