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

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/spf13/pflag"
	"golang.org/x/text/language"
	"golang.org/x/text/message"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/load"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/internal/encoding"
	"cuelang.org/go/internal/filetypes"
	"cuelang.org/go/internal/value"
)

// Disallow
// - block comments
// - old-style field comprehensions
// - space separator syntax
const syntaxVersion = -1000 + 100*2 + 1

var requestedVersion = os.Getenv("CUE_SYNTAX_OVERRIDE")

var defaultConfig = config{
	loadCfg: &load.Config{
		ParseFile: func(name string, src interface{}) (*ast.File, error) {
			version := syntaxVersion
			if requestedVersion != "" {
				switch {
				case strings.HasPrefix(requestedVersion, "v0.1"):
					version = -1000 + 100
				}
			}
			return parser.ParseFile(name, src,
				parser.FromVersion(version),
				parser.ParseComments,
			)
		},
	},
}

var runtime = &cue.Runtime{}

var inTest = false

func exitIfErr(cmd *Command, inst *cue.Instance, err error, fatal bool) {
	exitOnErr(cmd, err, fatal)
}

func getLang() language.Tag {
	loc := os.Getenv("LC_ALL")
	if loc == "" {
		loc = os.Getenv("LANG")
	}
	loc = strings.Split(loc, ".")[0]
	return language.Make(loc)
}

func exitOnErr(cmd *Command, err error, fatal bool) {
	if err == nil {
		return
	}

	// Link x/text as our localizer.
	p := message.NewPrinter(getLang())
	format := func(w io.Writer, format string, args ...interface{}) {
		p.Fprintf(w, format, args...)
	}

	cwd, _ := os.Getwd()

	w := &bytes.Buffer{}
	errors.Print(w, err, &errors.Config{
		Format:  format,
		Cwd:     cwd,
		ToSlash: inTest,
	})

	b := w.Bytes()
	_, _ = cmd.Stderr().Write(b)
	if fatal {
		exit()
	}
}

func loadFromArgs(cmd *Command, args []string, cfg *load.Config) []*build.Instance {
	binst := load.Instances(args, cfg)
	if len(binst) == 0 {
		return nil
	}

	return binst
}

// A buildPlan defines what should be done based on command line
// arguments and flags.
//
// TODO: allow --merge/-m to mix in other packages.
type buildPlan struct {
	cmd   *Command
	insts []*build.Instance

	// instance is a pre-compiled instance, which exists if value files are
	// being processed, which may require a schema to decode.
	instance *cue.Instance

	cfg *config

	// If orphanFiles are mixed with CUE files and/or if placement flags are used,
	// the instance is also included in insts.
	importing      bool
	mergeData      bool // do not merge individual data files.
	orphaned       []*decoderInfo
	orphanInstance *build.Instance
	// imported files are files that were orphaned in the build instance, but
	// were placed in the instance by using one the --files, --list or --path
	// flags.
	imported []*ast.File

	expressions []ast.Expr // only evaluate these expressions within results
	schema      ast.Expr   // selects schema in instance for orphaned values

	// orphan placement flags.
	perFile    bool
	useList    bool
	path       []ast.Label
	useContext bool

	// outFile defines the file to output to. Default is CUE stdout.
	outFile *build.File

	encConfig *encoding.Config
}

// instances iterates either over a list of instances, or a list of
// data files. In the latter case, there must be either 0 or 1 other
// instance, with which the data instance may be merged.
func (b *buildPlan) instances() iterator {
	var i iterator
	switch {
	case len(b.orphaned) > 0:
		i = newStreamingIterator(b)
	case len(b.insts) > 0:
		i = &instanceIterator{
			inst: b.instance,
			a:    buildInstances(b.cmd, b.insts),
			i:    -1,
		}
	default:
		i = &instanceIterator{a: []*cue.Instance{b.instance}, i: -1}
		b.instance = nil
	}
	if len(b.expressions) > 0 {
		return &expressionIter{
			iter: i,
			expr: b.expressions,
			i:    len(b.expressions),
		}
	}
	return i
}

type iterator interface {
	scan() bool
	value() cue.Value
	instance() *cue.Instance // may return nil
	file() *ast.File         // may return nil
	err() error
	close()
	id() string
}

type instanceIterator struct {
	inst *cue.Instance
	a    []*cue.Instance
	i    int
	e    error
}

func (i *instanceIterator) scan() bool {
	i.i++
	return i.i < len(i.a) && i.e == nil
}

func (i *instanceIterator) close()     {}
func (i *instanceIterator) err() error { return i.e }
func (i *instanceIterator) value() cue.Value {
	v := i.a[i.i].Value()
	if i.inst != nil {
		v = v.Unify(i.inst.Value())
	}
	return v
}
func (i *instanceIterator) instance() *cue.Instance {
	if i.inst != nil {
		return nil
	}
	return i.a[i.i]
}
func (i *instanceIterator) file() *ast.File { return nil }
func (i *instanceIterator) id() string      { return i.a[i.i].Dir }

type streamingIterator struct {
	r   *cue.Runtime
	b   *buildPlan
	cfg *encoding.Config
	a   []*decoderInfo
	dec *encoding.Decoder
	v   cue.Value
	f   *ast.File
	e   error
}

func newStreamingIterator(b *buildPlan) *streamingIterator {
	i := &streamingIterator{
		cfg: b.encConfig,
		a:   b.orphaned,
		b:   b,
	}

	// TODO: use orphanedSchema
	i.r = &cue.Runtime{}
	if v := b.encConfig.Schema; v.Exists() {
		i.r = value.ConvertToRuntime(v.Context())
	}

	return i
}

func (i *streamingIterator) file() *ast.File         { return i.f }
func (i *streamingIterator) value() cue.Value        { return i.v }
func (i *streamingIterator) instance() *cue.Instance { return nil }

func (i *streamingIterator) id() string {
	return ""
}

func (i *streamingIterator) scan() bool {
	if i.e != nil {
		return false
	}

	// advance to next value
	if i.dec != nil && !i.dec.Done() {
		i.dec.Next()
	}

	// advance to next stream if necessary
	for i.dec == nil || i.dec.Done() {
		if i.dec != nil {
			i.dec.Close()
			i.dec = nil
		}
		if len(i.a) == 0 {
			return false
		}

		i.dec = i.a[0].dec(i.b)
		if i.e = i.dec.Err(); i.e != nil {
			return false
		}
		i.a = i.a[1:]
	}

	// compose value
	i.f = i.dec.File()
	inst, err := i.r.CompileFile(i.f)
	if err != nil {
		i.e = err
		return false
	}
	i.v = inst.Value()
	if schema := i.b.encConfig.Schema; schema.Exists() {
		i.e = schema.Err()
		if i.e == nil {
			i.v = i.v.Unify(schema) // TODO(required fields): don't merge in schema
			i.e = i.v.Err()
		}
		i.f = nil
	}
	return i.e == nil
}

func (i *streamingIterator) close() {
	if i.dec != nil {
		i.dec.Close()
		i.dec = nil
	}
}

func (i *streamingIterator) err() error {
	if i.dec != nil {
		if err := i.dec.Err(); err != nil {
			return err
		}
	}
	return i.e
}

type expressionIter struct {
	iter iterator
	expr []ast.Expr
	i    int
}

func (i *expressionIter) err() error { return i.iter.err() }
func (i *expressionIter) close()     { i.iter.close() }
func (i *expressionIter) id() string { return i.iter.id() }

func (i *expressionIter) scan() bool {
	i.i++
	if i.i < len(i.expr) {
		return true
	}
	if !i.iter.scan() {
		return false
	}
	i.i = 0
	return true
}

func (i *expressionIter) file() *ast.File         { return nil }
func (i *expressionIter) instance() *cue.Instance { return nil }

func (i *expressionIter) value() cue.Value {
	if len(i.expr) == 0 {
		return i.iter.value()
	}
	v := i.iter.value()
	return v.Context().BuildExpr(i.expr[i.i],
		cue.Scope(v),
		cue.InferBuiltins(true),
	)
}

type config struct {
	outMode filetypes.Mode

	fileFilter     string
	reFile         *regexp.Regexp
	encoding       build.Encoding
	interpretation build.Interpretation

	overrideDefault bool

	noMerge bool // do not merge individual data files.

	loadCfg *load.Config
}

func newBuildPlan(cmd *Command, args []string, cfg *config) (p *buildPlan, err error) {
	if cfg == nil {
		cfg = &defaultConfig
	}
	if cfg.loadCfg == nil {
		cfg.loadCfg = defaultConfig.loadCfg
	}
	cfg.loadCfg.Stdin = cmd.InOrStdin()

	p = &buildPlan{cfg: cfg, cmd: cmd, importing: cfg.loadCfg.DataFiles}

	if err := p.parseFlags(); err != nil {
		return nil, err
	}
	re, err := regexp.Compile(p.cfg.fileFilter)
	if err != nil {
		return nil, err
	}
	cfg.reFile = re

	if err := setTags(cmd.Flags(), cfg.loadCfg); err != nil {
		return nil, err
	}

	return p, nil
}

func (p *buildPlan) matchFile(file string) bool {
	return p.cfg.reFile.MatchString(file)
}

func setTags(f *pflag.FlagSet, cfg *load.Config) error {
	tags, _ := f.GetStringArray(string(flagInject))
	cfg.Tags = tags
	return nil
}

type decoderInfo struct {
	file *build.File
	d    *encoding.Decoder // may be nil if delayed
}

func (d *decoderInfo) dec(b *buildPlan) *encoding.Decoder {
	if d.d == nil {
		d.d = encoding.NewDecoder(d.file, b.encConfig)
	}
	return d.d
}

func (d *decoderInfo) close() {
	if d.d != nil {
		d.d.Close()
	}
}

// getDecoders takes the orphaned files of the given instance and splits them in
// schemas and values, saving the build.File and encoding.Decoder in the
// returned slices. It is up to the caller to Close any of the decoders that are
// returned.
func (p *buildPlan) getDecoders(b *build.Instance) (schemas, values []*decoderInfo, err error) {
	files := b.OrphanedFiles
	if p.cfg.overrideDefault {
		files = append(files, b.UnknownFiles...)
	}
	for _, f := range files {
		if !p.matchFile(f.Filename) && f.Filename != "-" {
			continue
		}
		if p.cfg.overrideDefault {
			f.Encoding = p.cfg.encoding
			f.Interpretation = p.cfg.interpretation
		}
		switch f.Encoding {
		case build.Protobuf, build.YAML, build.JSON, build.JSONL,
			build.Text, build.Binary:
			if f.Interpretation == build.ProtobufJSON {
				// Need a schema.
				values = append(values, &decoderInfo{f, nil})
				continue
			}
		case build.TextProto:
			if p.importing {
				return schemas, values, errors.Newf(token.NoPos,
					"cannot import textproto files")
			}
			// Needs to be decoded after any schema.
			values = append(values, &decoderInfo{f, nil})
			continue
		default:
			return schemas, values, errors.Newf(token.NoPos,
				"unsupported encoding %q", f.Encoding)
		}

		// We add the module root to the path if there is a module defined.
		c := *p.encConfig
		if b.Module != "" {
			c.ProtoPath = append(c.ProtoPath, b.Root)
		}
		d := encoding.NewDecoder(f, &c)

		fi, err := filetypes.FromFile(f, p.cfg.outMode)
		if err != nil {
			return schemas, values, err
		}
		switch {
		// case !fi.Schema: // TODO: value/schema/auto
		// 	values = append(values, d)
		case fi.Form != build.Schema && fi.Form != build.Final:
			values = append(values, &decoderInfo{f, d})

		case f.Interpretation != build.Auto:
			schemas = append(schemas, &decoderInfo{f, d})

		case d.Interpretation() == "":
			values = append(values, &decoderInfo{f, d})

		default:
			schemas = append(schemas, &decoderInfo{f, d})
		}
	}
	return schemas, values, nil
}

// importFiles imports orphan files for existing instances. Note that during
// import, both schemas and non-schemas are placed (TODO: should we allow schema
// mode here as well? It seems that the existing package should have enough
// typing to allow for schemas).
//
// It is a separate call to allow closing decoders between processing each
// package.
func (p *buildPlan) importFiles(b *build.Instance) error {
	// TODO: assume textproto is imported at top-level or just ignore them.

	schemas, values, err := p.getDecoders(b)
	for _, d := range append(schemas, values...) {
		defer d.close()
	}
	if err != nil {
		return err
	}
	return p.placeOrphans(b, append(schemas, values...))
}

func parseArgs(cmd *Command, args []string, cfg *config) (p *buildPlan, err error) {
	p, err = newBuildPlan(cmd, args, cfg)
	if err != nil {
		return nil, err
	}

	builds := loadFromArgs(cmd, args, cfg.loadCfg)
	if builds == nil {
		return nil, errors.Newf(token.NoPos, "invalid args")
	}

	if err := p.parsePlacementFlags(); err != nil {
		return nil, err
	}

	for _, b := range builds {
		if b.Err != nil {
			return nil, b.Err
		}
		switch {
		case !b.User:
			if p.importing {
				if err := p.importFiles(b); err != nil {
					return nil, err
				}
			}
			p.insts = append(p.insts, b)

		case p.orphanInstance != nil:
			return nil, errors.Newf(token.NoPos,
				"builds contain two file packages")

		default:
			p.orphanInstance = b
		}
	}

	if b := p.orphanInstance; b != nil {
		schemas, values, err := p.getDecoders(b)
		for _, d := range append(schemas, values...) {
			defer d.close()
		}
		if err != nil {
			return nil, err
		}

		if values == nil {
			values, schemas = schemas, values
		}

		for _, di := range schemas {
			d := di.dec(p)
			for ; !d.Done(); d.Next() {
				if err := b.AddSyntax(d.File()); err != nil {
					return nil, err
				}
			}
			if err := d.Err(); err != nil {
				return nil, err
			}
		}

		if len(p.insts) > 1 && p.schema != nil {
			return nil, errors.Newf(token.NoPos,
				"cannot use --schema/-d with flag more than one schema")
		}

		var schema *build.Instance
		switch n := len(p.insts); n {
		default:
			return nil, errors.Newf(token.NoPos,
				"too many packages defined (%d) in combination with files", n)
		case 1:
			if len(schemas) > 0 {
				return nil, errors.Newf(token.NoPos,
					"cannot combine packages with individual schema files")
			}
			schema = p.insts[0]
			p.insts = nil

		case 0:
			bb := *b
			schema = &bb
			b.BuildFiles = nil
			b.Files = nil
		}

		if schema != nil && len(schema.Files) > 0 {
			inst := buildInstances(p.cmd, []*build.Instance{schema})[0]

			if inst.Err != nil {
				return nil, err
			}
			p.instance = inst
			p.encConfig.Schema = inst.Value()
			if p.schema != nil {
				v := inst.Eval(p.schema)
				if err := v.Err(); err != nil {
					return nil, err
				}
				p.encConfig.Schema = v
			}
		}

		switch {
		default:
			fallthrough

		case p.schema != nil:
			p.orphaned = values

		case p.mergeData, p.usePlacement(), p.importing:
			if err = p.placeOrphans(b, values); err != nil {
				return nil, err
			}

		}

		if len(b.Files) > 0 {
			p.insts = append(p.insts, b)
		}
	}

	if len(p.expressions) > 1 {
		p.encConfig.Stream = true
	}
	return p, nil
}

func (b *buildPlan) parseFlags() (err error) {
	b.mergeData = !b.cfg.noMerge && flagMerge.Bool(b.cmd)

	out := flagOut.String(b.cmd)
	outFile := flagOutFile.String(b.cmd)

	if strings.Contains(out, ":") && strings.Contains(outFile, ":") {
		return errors.Newf(token.NoPos,
			"cannot specify qualifier in both --out and --outfile")
	}
	if outFile == "" {
		outFile = "-"
	}
	if out != "" {
		outFile = out + ":" + outFile
	}
	b.outFile, err = filetypes.ParseFile(outFile, b.cfg.outMode)
	if err != nil {
		return err
	}

	for _, e := range flagExpression.StringArray(b.cmd) {
		expr, err := parser.ParseExpr("--expression", e)
		if err != nil {
			return err
		}
		b.expressions = append(b.expressions, expr)
	}
	if s := flagSchema.String(b.cmd); s != "" {
		b.schema, err = parser.ParseExpr("--schema", s)
		if err != nil {
			return err
		}
	}
	if s := flagGlob.String(b.cmd); s != "" {
		// Set a default file filter to only include json and yaml files
		b.cfg.fileFilter = s
	}
	b.encConfig = &encoding.Config{
		Force:     flagForce.Bool(b.cmd),
		Mode:      b.cfg.outMode,
		Stdin:     b.cmd.InOrStdin(),
		Stdout:    b.cmd.OutOrStdout(),
		ProtoPath: flagProtoPath.StringArray(b.cmd),
		AllErrors: flagAllErrors.Bool(b.cmd),
		PkgName:   flagPackage.String(b.cmd),
		Strict:    flagStrict.Bool(b.cmd),
	}
	return nil
}

func buildInstances(cmd *Command, binst []*build.Instance) []*cue.Instance {
	// TODO:
	// If there are no files and User is true, then use those?
	// Always use all files in user mode?
	instances := cue.Build(binst)
	for _, inst := range instances {
		// TODO: consider merging errors of multiple files, but ensure
		// duplicates are removed.
		exitIfErr(cmd, inst, inst.Err, true)
	}

	if flagIgnore.Bool(cmd) {
		return instances
	}

	// TODO check errors after the fact in case of ignore.
	for _, inst := range instances {
		// TODO: consider merging errors of multiple files, but ensure
		// duplicates are removed.
		exitIfErr(cmd, inst, inst.Value().Validate(), !flagIgnore.Bool(cmd))
	}
	return instances
}

func buildToolInstances(cmd *Command, binst []*build.Instance) ([]*cue.Instance, error) {
	instances := cue.Build(binst)
	for _, inst := range instances {
		if inst.Err != nil {
			return nil, inst.Err
		}
	}

	// TODO check errors after the fact in case of ignore.
	for _, inst := range instances {
		if err := inst.Value().Validate(); err != nil {
			return nil, err
		}
	}
	return instances, nil
}

func buildTools(cmd *Command, args []string) (*cue.Instance, error) {

	cfg := &load.Config{
		Tools: true,
	}
	f := cmd.cmd.Flags()
	if err := setTags(f, cfg); err != nil {
		return nil, err
	}

	binst := loadFromArgs(cmd, args, cfg)
	if len(binst) == 0 {
		return nil, nil
	}
	included := map[string]bool{}

	ti := binst[0].Context().NewInstance(binst[0].Root, nil)
	for _, inst := range binst {
		k := 0
		for _, f := range inst.Files {
			if strings.HasSuffix(f.Filename, "_tool.cue") {
				if !included[f.Filename] {
					_ = ti.AddSyntax(f)
					included[f.Filename] = true
				}
				continue
			}
			inst.Files[k] = f
			k++
		}
		inst.Files = inst.Files[:k]
	}

	insts, err := buildToolInstances(cmd, binst)
	if err != nil {
		return nil, err
	}

	inst := insts[0]
	if len(insts) > 1 {
		inst = cue.Merge(insts...)
	}

	r := value.ConvertToRuntime(inst.Value().Context())
	for _, b := range binst {
		for _, i := range b.Imports {
			if _, err := r.Build(i); err != nil {
				return nil, err
			}
		}
	}

	// Set path equal to the package from which it is loading.
	ti.ImportPath = binst[0].ImportPath

	inst = inst.Build(ti)
	return inst, inst.Err
}

func shortFile(root string, f *build.File) string {
	dir, _ := filepath.Rel(root, f.Filename)
	if dir == "" {
		return f.Filename
	}
	if !filepath.IsAbs(dir) {
		dir = "." + string(filepath.Separator) + dir
	}
	return dir
}
