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

import (
	"log"
	"sort"
	"strconv"

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

type LoadFunc func(pos token.Pos, path string) *Instance

type cueError = errors.Error

type buildError struct {
	cueError
	inputs []token.Pos
}

func (e *buildError) InputPositions() []token.Pos {
	return e.inputs
}

func (inst *Instance) complete() errors.Error {
	// TODO: handle case-insensitive collisions.
	// dir := inst.Dir
	// names := []string{}
	// for _, src := range sources {
	// 	names = append(names, src.path)
	// }
	// f1, f2 := str.FoldDup(names)
	// if f1 != "" {
	// 	return nil, fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2)
	// }

	var (
		c        = inst.ctxt
		imported = map[string][]token.Pos{}
	)

	for _, f := range inst.Files {
		for _, decl := range f.Decls {
			d, ok := decl.(*ast.ImportDecl)
			if !ok {
				continue
			}
			for _, spec := range d.Specs {
				quoted := spec.Path.Value
				path, err := strconv.Unquote(quoted)
				if err != nil {
					// TODO: remove panic
					log.Panicf("%s: parser returned invalid quoted string: <%s>", f.Filename, quoted)
				}
				imported[path] = append(imported[path], spec.Pos())
			}
		}
	}

	paths := make([]string, 0, len(imported))
	for path := range imported {
		paths = append(paths, path)
		if path == "" {
			return &buildError{
				errors.Newf(token.NoPos, "empty import path"),
				imported[path],
			}
		}
	}

	sort.Strings(paths)

	if inst.loadFunc != nil {
		for i, path := range paths {
			isLocal := IsLocalImport(path)
			if isLocal {
				// path = dirToImportPath(filepath.Join(dir, path))
			}

			imp := c.imports[path]
			if imp == nil {
				pos := token.NoPos
				if len(imported[path]) > 0 {
					pos = imported[path][0]
				}
				imp = inst.loadFunc(pos, path)
				if imp == nil {
					continue
				}
				if imp.Err != nil {
					return nil
				}
				imp.ImportPath = path
				// imp.parent = inst
				c.imports[path] = imp
				// imp.parent = nil
			} else if imp.parent != nil {
				// TODO: report a standard cycle message.
				//       cycle is now handled explicitly in loader
			}
			paths[i] = imp.ImportPath

			inst.addImport(imp)
			if imp.Incomplete {
				inst.Incomplete = true
			}
		}
	}

	inst.ImportPaths = paths
	inst.ImportPos = imported

	// Build full dependencies
	deps := make(map[string]*Instance)
	var q []*Instance
	q = append(q, inst.Imports...)
	for i := 0; i < len(q); i++ {
		p1 := q[i]
		path := p1.ImportPath
		// The same import path could produce an error or not,
		// depending on what tries to import it.
		// Prefer to record entries with errors, so we can report them.
		// p0 := deps[path]
		// if err0, err1 := lastError(p0), lastError(p1); p0 == nil || err1 != nil && (err0 == nil || len(err0.ImportStack) > len(err1.ImportStack)) {
		// 	deps[path] = p1
		// 	for _, p2 := range p1.Imports {
		// 		if deps[p2.ImportPath] != p2 {
		// 			q = append(q, p2)
		// 		}
		// 	}
		// }
		if _, ok := deps[path]; !ok {
			deps[path] = p1
		}
	}
	inst.Deps = make([]string, 0, len(deps))
	for dep := range deps {
		inst.Deps = append(inst.Deps, dep)
	}
	sort.Strings(inst.Deps)

	for _, dep := range inst.Deps {
		p1 := deps[dep]
		if p1 == nil {
			panic("impossible: missing entry in package cache for " + dep + " imported by " + inst.ImportPath)
		}
		if p1.Err != nil {
			inst.DepsErrors = append(inst.DepsErrors, p1.Err)
		}
	}

	return nil
}
