// Copyright 2019 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 protobuf defines functionality for parsing protocol buffer
// definitions and instances.
//
// Proto definition mapping follows the guidelines of mapping Proto to JSON as
// discussed in https://developers.google.com/protocol-buffers/docs/proto3, and
// carries some of the mapping further when possible with CUE.
//
//
// Package Paths
//
// If a .proto file contains a go_package directive, it will be used as the
// destination package fo the generated .cue files. A common use case is to
// generate the CUE in the same directory as the .proto definition. If a
// destination package is not within the current CUE module, it will be written
// relative to the pkg directory.
//
// If a .proto file does not specify go_package, it will convert a proto package
// "google.parent.sub" to the import path "googleapis.com/google/parent/sub".
// It is safe to mix package with and without a go_package within the same
// project.
//
// Type Mappings
//
// The following type mappings of defintions apply:
//
//   Proto type     CUE type/def     Comments
//   message        struct           Message fields become CUE fields, whereby
//                                   names are mapped to lowerCamelCase.
//   enum           e1 | e2 | ...    Where ex are strings. A separate mapping is
//                                   generated to obtain the numeric values.
//   map<K, V>      { <>: V }        All keys are converted to strings.
//   repeated V     [...V]           null is accepted as the empty list [].
//   bool           bool
//   string         string
//   bytes          bytes            A base64-encoded string when converted to JSON.
//   int32, fixed32 int32            An integer with bounds as defined by int32.
//   uint32         uint32           An integer with bounds as defined by uint32.
//   int64, fixed64 int64            An integer with bounds as defined by int64.
//   uint64         uint64           An integer with bounds as defined by uint64.
//   float          float32          A number with bounds as defined by float32.
//   double         float64          A number with bounds as defined by float64.
//   Struct         struct           See struct.proto.
//   Value          _                See struct.proto.
//   ListValue      [...]            See struct.proto.
//   NullValue      null             See struct.proto.
//   BoolValue      bool             See struct.proto.
//   StringValue    string           See struct.proto.
//   NumberValue    number           See struct.proto.
//   StringValue    string           See struct.proto.
//   Empty          struct.MaxFields(0)
//   Timestamp      time.Time        See struct.proto.
//   Duration       time.Duration    See struct.proto.
//
// Protobuf definitions can be annotated with CUE constraints that are included
// in the generated CUE:
//    (cue.val)     string        CUE expression defining a constraint for this
//                                field. The string may refer to other fields
//                                in a message definition using their JSON name.
//
//    (cue.opt)     FieldOptions
//       required   bool          Defines the field is required. Use with
//                                caution.
//
package protobuf

// TODO mappings:
//
// Wrapper types	various types	2, "2", "foo", true, "true", null, 0, …	Wrappers use the same representation in JSON as the wrapped primitive type, except that null is allowed and preserved during data conversion and transfer.
// FieldMask	string	"f.fooBar,h"	See field_mask.proto.
//   Any            {"@type":"url",  See struct.proto.
//                   f1: value,
//                   ...}

import (
	"os"
	"path/filepath"
	"sort"
	"strings"

	"cuelang.org/go/cue/ast"
	"cuelang.org/go/cue/build"
	"cuelang.org/go/cue/errors"
	"cuelang.org/go/cue/format"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"github.com/mpvl/unique"
)

// Config specifies the environment into which to parse a proto definition file.
type Config struct {
	// Root specifies the root of the CUE project, which typically coincides
	// with, for example, a version control repository root or the Go module.
	// Any imports of proto files within the directory tree of this of this root
	// are considered to be "project files" and are generated at the
	// corresponding location with this hierarchy. Any other imports are
	// considered to be external. Files for such imports are rooted under the
	// $Root/pkg/, using the Go package path specified in the .proto file.
	Root string

	// Module is the Go package import path of the module root. It is the value
	// as after "module" in a go.mod file, if a module file is present.
	Module string // TODO: determine automatically if unspecified.

	// Paths defines the include directory in which to search for imports.
	Paths []string
}

// An Extractor converts a collection of proto files, typically belonging to one
// repo or module, to CUE. It thereby observes the CUE package layout.
//
// CUE observes the same package layout as Go and requires .proto files to have
// the go_package directive. Generated CUE files are put in the same directory
// as their corresponding .proto files if the .proto files are located in the
// specified Root (or current working directory if none is specified).
// All other imported files are assigned to the CUE pkg dir ($Root/pkg)
// according to their Go package import path.
//
type Extractor struct {
	root   string
	cwd    string
	module string
	paths  []string

	fileCache map[string]result
	imports   map[string]*build.Instance

	errs errors.Error
	done bool
}

type result struct {
	p   *protoConverter
	err error
}

// NewExtractor creates an Extractor. If the configuration contained any errors
// it will be observable by the Err method fo the Extractor. It is safe,
// however, to only check errors after building the output.
func NewExtractor(c *Config) *Extractor {
	cwd, _ := os.Getwd()
	b := &Extractor{
		root:      c.Root,
		cwd:       cwd,
		paths:     c.Paths,
		module:    c.Module,
		fileCache: map[string]result{},
		imports:   map[string]*build.Instance{},
	}

	if b.root == "" {
		b.root = b.cwd
	}

	return b
}

// Err returns the errors accumulated during testing. The returned error may be
// of type cuelang.org/go/cue/errors.List.
func (b *Extractor) Err() error {
	return b.errs
}

func (b *Extractor) addErr(err error) {
	b.errs = errors.Append(b.errs, errors.Promote(err, "unknown error"))
}

// AddFile adds a proto definition file to be converted into CUE by the builder.
// Relatives paths are always taken relative to the Root with which the b is
// configured.
//
// AddFile assumes that the proto file compiles with protoc and may not report
// an error if it does not. Imports are resolved using the paths defined in
// Config.
//
func (b *Extractor) AddFile(filename string, src interface{}) error {
	if b.done {
		err := errors.Newf(token.NoPos,
			"protobuf: cannot call AddFile: Instances was already called")
		b.errs = errors.Append(b.errs, err)
		return err
	}
	if b.root != b.cwd && !filepath.IsAbs(filename) {
		filename = filepath.Join(b.root, filename)
	}
	_, err := b.parse(filename, src)
	return err
}

// TODO: some way of (recursively) adding multiple proto files with filter.

// Files returns a File for each proto file that was added or imported,
// recursively.
func (b *Extractor) Files() (files []*ast.File, err error) {
	defer func() { err = b.Err() }()
	b.done = true

	instances, err := b.Instances()
	if err != nil {
		return nil, err
	}

	for _, p := range instances {
		for _, f := range p.Files {
			files = append(files, f)
		}
	}
	return files, nil
}

// Instances creates a build.Instances for every package for which a proto file
// was added to the builder. This includes transitive dependencies. It does not
// write the generated files to disk.
//
// The returned instances can be passed to cue.Build to generated the
// corresponding CUE instances.
//
// All import paths are located within the specified Root, where external
// packages are located under $Root/pkg. Instances for builtin (like time)
// packages may be omitted, and if not will have no associated files.
func (b *Extractor) Instances() (instances []*build.Instance, err error) {
	defer func() { err = b.Err() }()
	b.done = true

	for _, r := range b.fileCache {
		if r.err != nil {
			b.addErr(r.err)
			continue
		}
		inst := b.getInst(r.p)
		if inst == nil {
			continue
		}

		// Set canonical CUE path for generated file.
		f := r.p.file
		base := filepath.Base(f.Filename)
		base = base[:len(base)-len(".proto")] + "_proto_gen.cue"
		f.Filename = filepath.Join(inst.Dir, base)
		buf, err := format.Node(f)
		if err != nil {
			b.addErr(err)
			// return nil, err
			continue
		}
		f, err = parser.ParseFile(f.Filename, buf, parser.ParseComments)
		if err != nil {
			b.addErr(err)
			continue
		}

		inst.Files = append(inst.Files, f)
		// inst.CUEFiles = append(inst.CUEFiles, f.Filename)
		// err := parser.Resolve(f)
		// if err != nil {
		// 	return nil, err
		// }

		for pkg := range r.p.imported {
			inst.ImportPaths = append(inst.ImportPaths, pkg)
		}
	}

	for _, p := range b.imports {
		instances = append(instances, p)
		sort.Strings(p.ImportPaths)
		unique.Strings(&p.ImportPaths)
		for _, i := range p.ImportPaths {
			if imp := b.imports[i]; imp != nil {
				p.Imports = append(p.Imports, imp)
			}
		}

		sort.Slice(p.Files, func(i, j int) bool {
			return p.Files[i].Filename < p.Files[j].Filename
		})
	}
	sort.Slice(instances, func(i, j int) bool {
		return instances[i].ImportPath < instances[j].ImportPath
	})

	if err != nil {
		return instances, err
	}
	return instances, nil
}

func (b *Extractor) getInst(p *protoConverter) *build.Instance {
	if b.errs != nil {
		return nil
	}
	importPath := p.importPath()
	if importPath == "" {
		err := errors.Newf(token.NoPos,
			"no package clause for proto package %q in file %s", p.id, p.file.Filename)
		b.errs = errors.Append(b.errs, err)
		// TODO: find an alternative. Is proto package good enough?
		return nil
	}

	dir := b.root
	path := importPath
	if !strings.HasPrefix(path, b.module) {
		dir = filepath.Join(dir, "pkg", path)
	} else {
		dir = filepath.Join(dir, path[len(b.module)+1:])
		want := filepath.Dir(p.file.Filename)
		if !filepath.IsAbs(want) {
			want = filepath.Join(b.root, want)
		}
		if dir != want {
			err := errors.Newf(token.NoPos,
				"file %s mapped to inconsistent path %s; module name %q may be inconsistent with root dir %s",
				want, dir, b.module, b.root,
			)
			b.errs = errors.Append(b.errs, err)
		}
	}

	inst := b.imports[importPath]
	if inst == nil {
		inst = &build.Instance{
			Root:        b.root,
			Dir:         dir,
			ImportPath:  importPath,
			PkgName:     p.shortPkgName,
			DisplayPath: p.protoPkg,
		}
		b.imports[importPath] = inst
	}
	return inst
}

// Extract parses a single proto file and returns its contents translated to a CUE
// file. If src is not nil, it will use this as the contents of the file. It may
// be a string, []byte or io.Reader. Otherwise Extract will open the given file
// name at the fully qualified path.
//
// Extract assumes the proto file compiles with protoc and may not report an error
// if it does not. Imports are resolved using the paths defined in Config.
//
func Extract(filename string, src interface{}, c *Config) (f *ast.File, err error) {
	if c == nil {
		c = &Config{}
	}
	b := NewExtractor(c)

	p, err := b.parse(filename, src)
	if err != nil {
		return nil, err
	}
	p.file.Filename = filename[:len(filename)-len(".proto")] + "_gen.cue"
	return p.file, b.Err()
}

// TODO
// func GenDefinition

// func MarshalText(cue.Value) (string, error) {
// 	return "", nil
// }

// func MarshalBytes(cue.Value) ([]byte, error) {
// 	return nil, nil
// }

// func UnmarshalText(descriptor cue.Value, b string) (ast.Expr, error) {
// 	return nil, nil
// }

// func UnmarshalBytes(descriptor cue.Value, b []byte) (ast.Expr, error) {
// 	return nil, nil
// }
