// Copyright 2020 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 runtime

import (
	"strings"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/ast/astutil"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/core/adt"
	"cuelang.org/go/internal/core/compile"
)

type Config struct {
	Runtime    *Runtime
	Filename   string
	ImportPath string

	compile.Config
}

// Build builds b and all its transitive dependencies, insofar they have not
// been build yet.
func (x *Runtime) Build(cfg *Config, b *build.Instance) (v *adt.Vertex, errs errors.Error) {
	if err := b.Complete(); err != nil {
		return nil, b.Err
	}
	if v := x.getNodeFromInstance(b); v != nil {
		return v, b.Err
	}
	// TODO: clear cache of old implementation.
	// if s := b.ImportPath; s != "" {
	// 	// Use cached result, if available.
	// 	if v, err := x.LoadImport(s); v != nil || err != nil {
	// 		return v, err
	// 	}
	// }

	errs = b.Err

	// Build transitive dependencies.
	for _, file := range b.Files {
		file.VisitImports(func(d *ast.ImportDecl) {
			for _, s := range d.Specs {
				errs = errors.Append(errs, x.buildSpec(cfg, b, s))
			}
		})
	}

	err := x.ResolveFiles(b)
	errs = errors.Append(errs, err)

	var cc *compile.Config
	if cfg != nil {
		cc = &cfg.Config
	}
	if cfg != nil && cfg.ImportPath != "" {
		b.ImportPath = cfg.ImportPath
		b.PkgName = astutil.ImportPathName(b.ImportPath)
	}
	v, err = compile.Files(cc, x, b.ID(), b.Files...)
	errs = errors.Append(errs, err)

	if errs != nil {
		v = adt.ToVertex(&adt.Bottom{Err: errs})
		b.Err = errs
	}

	x.AddInst(b.ImportPath, v, b)

	return v, errs
}

func dummyLoad(token.Pos, string) *build.Instance { return nil }

func (r *Runtime) Compile(cfg *Config, source interface{}) (*adt.Vertex, *build.Instance) {
	ctx := build.NewContext()
	var filename string
	if cfg != nil && cfg.Filename != "" {
		filename = cfg.Filename
	}
	p := ctx.NewInstance(filename, dummyLoad)
	if err := p.AddFile(filename, source); err != nil {
		return nil, p
	}
	v, _ := r.Build(cfg, p)
	return v, p
}

func (r *Runtime) CompileFile(cfg *Config, file *ast.File) (*adt.Vertex, *build.Instance) {
	ctx := build.NewContext()
	filename := file.Filename
	if cfg != nil && cfg.Filename != "" {
		filename = cfg.Filename
	}
	p := ctx.NewInstance(filename, dummyLoad)
	err := p.AddSyntax(file)
	if err != nil {
		return nil, p
	}
	_, p.PkgName, _ = internal.PackageInfo(file)
	v, _ := r.Build(cfg, p)
	return v, p
}

func (x *Runtime) buildSpec(cfg *Config, b *build.Instance, spec *ast.ImportSpec) (errs errors.Error) {
	info, err := astutil.ParseImportSpec(spec)
	if err != nil {
		return errors.Promote(err, "invalid import path")
	}

	pkg := b.LookupImport(info.ID)
	if pkg == nil {
		if strings.Contains(info.ID, ".") {
			return errors.Newf(spec.Pos(),
				"package %q imported but not defined in %s",
				info.ID, b.ImportPath)
		}
		return nil // TODO: check the builtin package exists here.
	}

	if v := x.index.importsByBuild[pkg]; v != nil {
		return pkg.Err
	}

	if _, err := x.Build(cfg, pkg); err != nil {
		return err
	}

	return nil
}
