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

import (
	"fmt"
	"path/filepath"
	"strings"

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

func lastError(p *build.Instance) *PackageError {
	if p == nil {
		return nil
	}
	switch v := p.Err.(type) {
	case *PackageError:
		return v
	}
	return nil
}

func report(p *build.Instance, err *PackageError) {
	if err != nil {
		p.ReportError(err)
	}
}

// A PackageError describes an error loading information about a package.
type PackageError struct {
	ImportStack    []string  // shortest path from package named on command line to this one
	Pos            token.Pos // position of error
	errors.Message           // the error itself
	IsImportCycle  bool      // the error is an import cycle
}

func (p *PackageError) Position() token.Pos         { return p.Pos }
func (p *PackageError) InputPositions() []token.Pos { return nil }
func (p *PackageError) Path() []string              { return nil }

func (l *loader) errPkgf(importPos []token.Pos, format string, args ...interface{}) *PackageError {
	err := &PackageError{
		ImportStack: l.stk.Copy(),
		Message:     errors.NewMessage(format, args),
	}
	err.fillPos(l.cfg.Dir, importPos)
	return err
}

func (p *PackageError) fillPos(cwd string, positions []token.Pos) {
	if len(positions) > 0 && !p.Pos.IsValid() {
		p.Pos = positions[0]
	}
}

// TODO(localize)
func (p *PackageError) Error() string {
	// Import cycles deserve special treatment.
	if p.IsImportCycle {
		return fmt.Sprintf("%s\npackage %s\n", p.Message, strings.Join(p.ImportStack, "\n\timports "))
	}
	if p.Pos.IsValid() {
		// Omit import stack. The full path to the file where the error
		// is the most important thing.
		return p.Pos.String() + ": " + p.Message.Error()
	}
	if len(p.ImportStack) == 0 {
		return p.Message.Error()
	}
	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Message.Error()
}

// NoFilesError is the error used by Import to describe a directory
// containing no usable source files. (It may still contain
// tool files, files hidden by build tags, and so on.)
type NoFilesError struct {
	Package *build.Instance

	ignored bool // whether any Go files were ignored due to build tags
}

func (e *NoFilesError) Position() token.Pos         { return token.NoPos }
func (e *NoFilesError) InputPositions() []token.Pos { return nil }
func (e *NoFilesError) Path() []string              { return nil }

// TODO(localize)
func (e *NoFilesError) Msg() (string, []interface{}) { return e.Error(), nil }

// TODO(localize)
func (e *NoFilesError) Error() string {
	// Count files beginning with _, which we will pretend don't exist at all.
	dummy := 0
	for _, name := range e.Package.IgnoredCUEFiles {
		if strings.HasPrefix(name, "_") {
			dummy++
		}
	}

	// path := shortPath(e.Package.Root, e.Package.Dir)
	path := e.Package.DisplayPath

	if len(e.Package.IgnoredCUEFiles) > dummy {
		// CUE files exist, but they were ignored due to build constraints.
		msg := "build constraints exclude all CUE files in " + path + " (ignored: "
		files := e.Package.IgnoredCUEFiles
		if len(files) > 4 {
			files = append(files[:4], "...")
		}
		for i, f := range files {
			files[i] = filepath.ToSlash(f)
		}
		msg += strings.Join(files, ", ")
		msg += ")"
		return msg
	}
	// if len(e.Package.TestCUEFiles) > 0 {
	// 	// Test CUE files exist, but we're not interested in them.
	// 	// The double-negative is unfortunate but we want e.Package.Dir
	// 	// to appear at the end of error message.
	// 	return "no non-test CUE files in " + e.Package.Dir
	// }
	return "no CUE files in " + path
}

// MultiplePackageError describes an attempt to build a package composed of
// CUE files from different packages.
type MultiplePackageError struct {
	Dir      string   // directory containing files
	Packages []string // package names found
	Files    []string // corresponding files: Files[i] declares package Packages[i]
}

func (e *MultiplePackageError) Position() token.Pos         { return token.NoPos }
func (e *MultiplePackageError) InputPositions() []token.Pos { return nil }
func (e *MultiplePackageError) Path() []string              { return nil }

func (e *MultiplePackageError) Msg() (string, []interface{}) {
	return "found packages %q (%s) and %s (%s) in %q", []interface{}{
		e.Packages[0],
		e.Files[0],
		e.Packages[1],
		e.Files[1],
		e.Dir,
	}
}

func (e *MultiplePackageError) Error() string {
	// Error string limited to two entries for compatibility.
	format, args := e.Msg()
	return fmt.Sprintf(format, args...)
}
