// 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.NewString("Hello"),
		out:  `"Hello"`,
	}, {
		expr: ast.NewList(
			ast.NewString("Hello"),
			ast.NewString("World"),
		),
		out: `["Hello","World"]`,
	}}
	for _, tc := range testCases {
		t.Run("", func(t *testing.T) {
			r := &Runtime{}
			inst, err := r.CompileExpr(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)
			}
		})
	}
}

// TestPartiallyResolved tests that the resolve will detect the usage of
// imports that are referenced by previously resolved nodes.
func TestPartiallyResolved(t *testing.T) {
	const importPath = "acme.com/foo"
	spec1 := &ast.ImportSpec{
		Path: ast.NewString(importPath),
	}
	spec2 := &ast.ImportSpec{
		Name: ast.NewIdent("bar"),
		Path: ast.NewString(importPath),
	}

	f := &ast.File{
		Decls: []ast.Decl{
			&ast.ImportDecl{Specs: []*ast.ImportSpec{spec1, spec2}},
			&ast.Field{
				Label: ast.NewIdent("X"),
				Value: &ast.Ident{Name: "foo", Node: spec1},
			},
			&ast.Alias{
				Ident: ast.NewIdent("Y"),
				Expr:  &ast.Ident{Name: "bar", Node: spec2},
			},
		},
		Imports: []*ast.ImportSpec{spec1, spec2},
	}

	err := resolveFile(nil, f, &build.Instance{
		Imports: []*build.Instance{{
			ImportPath: importPath,
			PkgName:    "foo",
		}},
	}, map[string]ast.Node{})

	if err != nil {
		t.Errorf("exected no error, found %v", err)
	}
}

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:pkg",
		files(`
		package pkg

		Number: 12
		`),
	}
	pkg3 := &bimport{
		"example.com/foo/v1:pkg3",
		files(`
		package pkg3

		List: [1,2,3]
		`),
	}

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

				import "math"

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

				import math2 "math"

				"Pi: \(math2.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"

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

				import pkg2 "pkg1"
				pkg1 :: pkg2.Object

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

				import bar "pkg1"
				import baz "example.com/foo/pkg2:pkg"

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

				import "example.com/foo/pkg2:pkg"

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

				import "example.com/foo/pkg2:pkg"

				"Hello \(pkg.Number)!"`),
		}),
		`"Hello 12!"`,
	}, {
		insts(pkg3, &bimport{"",
			files(
				`package test

				import "example.com/foo/v1:pkg3"

				"Hello \(pkg3.List[1])!"`),
		}),
		`"Hello 2!"`,
	}, {
		insts(pkg3, &bimport{"",
			files(
				`package test

				import "example.com/foo/v1:pkg3"

				pkg3: 3

				"Hello \(pkg3.List[1])!"`),
		}),
		`pkg3 redeclared as imported package name
	previous declaration at file0.cue:5:5`,
	}}
	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(pos token.Pos, path string) *build.Instance {
	bi := b.imports[path]
	if bi == nil {
		return nil
	}
	return b.build(bi)
}

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 == "" {
			instances = append(instances, b.build(bi))
		}
	}
	return
}

func (b *builder) build(bi *bimport) *build.Instance {
	path := bi.path
	if path == "" {
		path = "dir"
	}
	p := b.ctxt.NewInstance(path, b.load)
	for i, f := range bi.files {
		_ = p.AddFile(fmt.Sprintf("file%d.cue", i), f)
	}
	_ = p.Complete()
	return p
}
