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

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

func TestFromExpr(t *testing.T) {
	testCases := []struct {
		expr ast.Expr
		out  string
	}{{
		expr: &ast.BasicLit{Kind: token.STRING, Value: `"Hello"`},
		out:  `"Hello"`,
	}, {
		expr: &ast.ListLit{Elts: []ast.Expr{
			&ast.BasicLit{Kind: token.STRING, Value: `"Hello"`},
			&ast.BasicLit{Kind: token.STRING, Value: `"World"`},
		}},
		out: `["Hello","World"]`,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			inst, err := FromExpr(nil, tc.expr)
			if err != nil {
				t.Fatal(err)
			}
			ctx := inst.newContext()
			if got := debugStr(ctx, inst.eval(ctx)); got != tc.out {
				t.Errorf("\n got: %v; want %v", got, tc.out)
			}
		})
	}
}

func TestBuild(t *testing.T) {
	files := func(s ...string) []string { return s }
	insts := func(i ...*bimport) []*bimport { return i }
	pkg1 := &bimport{
		"pkg1",
		files(`
		package pkg1

		Object: "World"
		`),
	}
	pkg2 := &bimport{
		"example.com/foo/pkg2",
		files(`
		package pkg

		Number: 12
		`),
	}
	insts(pkg1, pkg2)

	testCases := []struct {
		instances []*bimport
		emit      string
	}{{
		insts(&bimport{"", files(`test: "ok"`)}),
		`<0>{test: "ok"}`,
		// }, {
		// 	insts(pkg1, &bimport{"",
		// 		files(
		// 			`package test

		// 			import "math"

		// 			"Pi: \(math.Pi)!"`)}),
		// 	`"Pi: 3.14159265358979323846264338327950288419716939937510582097494459!"`,
	}, {
		insts(pkg1, &bimport{"",
			files(
				`package test

				import "pkg1"

				"Hello \(pkg1.Object)!"`),
		}),
		`"Hello World!"`,
	}, {
		insts(pkg1, &bimport{"",
			files(
				`package test

				import "pkg1"
				pkg1: 1

				"Hello \(pkg1.Object)!"`),
		}),
		`pkg1 redeclared as imported package name
	previous declaration at file0.cue:4:5`,
	}, {
		insts(pkg1, &bimport{"",
			files(
				`package test

				import bar "pkg1"

				pkg1 Object: 3
				"Hello \(pkg1.Object)!"`),
		}),
		`imported and not used: "pkg1" as bar`,
	}, {
		insts(pkg2, &bimport{"",
			files(
				`package test

				import "example.com/foo/pkg2"

				"Hello \(pkg2.Number)!"`),
		}),
		`imported and not used: "example.com/foo/pkg2"`,
		// `file0.cue:5:14: unresolved reference pkg2`,
	}, {
		insts(pkg2, &bimport{"",
			files(
				`package test

				import "example.com/foo/pkg2"

				"Hello \(pkg.Number)!"`),
		}),
		`"Hello 12!"`,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			insts := Build(makeInstances(tc.instances))
			var got string
			if err := insts[0].Err; err != nil {
				got = err.Error()
			} else {
				got = strings.TrimSpace(fmt.Sprintf("%s\n", insts[0].Value()))
			}
			if got != tc.emit {
				t.Errorf("\n got: %s\nwant: %s", got, tc.emit)
			}
		})
	}
}

type builder struct {
	ctxt    *build.Context
	imports map[string]*bimport
}

func (b *builder) load(path string) *build.Instance {
	p := b.ctxt.NewInstance(path, b.load)
	bi := b.imports[path]
	if bi == nil {
		return nil
	}
	buildInstance(b.imports[path], p)
	return p
}

type bimport struct {
	path  string // "" means top-level
	files []string
}

func makeInstances(insts []*bimport) (instances []*build.Instance) {
	b := builder{
		ctxt:    build.NewContext(),
		imports: map[string]*bimport{},
	}
	for _, bi := range insts {
		if bi.path != "" {
			b.imports[bi.path] = bi
		}
	}
	for _, bi := range insts {
		if bi.path == "" {
			p := b.ctxt.NewInstance("dir", b.load)
			buildInstance(bi, p)
			instances = append(instances, p)
		}
	}
	return
}

func buildInstance(bi *bimport, p *build.Instance) {
	for i, f := range bi.files {
		p.AddFile(fmt.Sprintf("file%d.cue", i), f)
	}
	p.Complete()
}
