// 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 (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"unicode"

	"github.com/spf13/cobra"

	"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/format"
	"cuelang.org/go/cue/literal"
	"cuelang.org/go/cue/load"
	"cuelang.org/go/cue/parser"
	"cuelang.org/go/cue/token"
	"cuelang.org/go/encoding/json"
	"cuelang.org/go/encoding/protobuf"
	"cuelang.org/go/internal"
	"cuelang.org/go/internal/third_party/yaml"
)

func newImportCmd(c *Command) *cobra.Command {
	cmd := &cobra.Command{
		Use:   "import [mode] [inputs]",
		Short: "convert other formats to CUE files",
		Long: `import converts other formats, like JSON and YAML to CUE files

Files can either be specified explicitly, or inferred from the
specified packages. Within packages, import only looks for JSON
and YAML files by default (see the "filetypes" help topic for
more info). This behavior can be overridden by specifying one of
the following modes:

   Mode       Extensions
   json       Look for JSON files (.json, .jsonl, .ldjson).
   yaml       Look for YAML files (.yaml .yml).
   text       Look for text files (.txt).
   jsonschema Interpret JSON, YAML or CUE files as JSON Schema.
   openapi    Interpret JSON, YAML or CUE files as OpenAPI.
   auto       Look for JSON or YAML files and interpret them as
              data, JSON Schema, or OpenAPI, depending on
              existing fields.
   data       Look for JSON or YAML files and interpret them
              as data.
   proto      Convert Protocol buffer definition files and
              transitive dependencies.

For user-specified files the modes only affect the

auto mode

In auto mode, data files are interpreted based on some marker
fields. JSON Schema is identified by a top-level "$schema" field
with a URL of the form "https?://json-schema.org/.*schema#?".
OpenAPI is identified by the existence of a top-level field
"openapi", which must have a major semantic version of 3, and
the info.title and info.version fields.


proto mode

Proto mode converts .proto files containing Prototcol Buffer
definitions to CUE. The -I defines the path for includes. The
module root is added implicitly if it exists.

The package name for a converted file is derived from the
go_package option. It can be overridden with the -p flag.

A module root must be specified if a .proto files includes other
files within the module. Files include from outside the module
are also imported and stored within the cue.mod directory. The
import path is defined by either the go_package option or, in the
absence of this option, the googleapis.com/<proto package>
convention.

The following command imports all .proto files in all
subdirectories as well all dependencies.

   cue import proto -I ../include ./...

The module root is implicitly added as an import path.


JSON/YAML mode

The -f option allows overwriting of existing files. This only
applies to files generated for explicitly specified files or
files contained in explicitly specified packages.

Use the -R option in addition to overwrite files generated for
transitive dependencies (files written to cue.mod/gen/...).

The -n option is a regexp used to filter file names in the
matched package directories.

The -I flag is used to specify import paths for proto mode.
The module root is implicitly added as an import if it exists.

Examples:

  # Convert individual files:
  $ cue import foo.json bar.json  # create foo.cue and bar.cue

  # Convert all json files in the indicated directories:
  $ cue import json ./...

The "flags" help topic describes how to assign values to a
specific path within a CUE namespace. Some examples of that

Examples:

  $ cat <<EOF > foo.yaml
  kind: Service
  name: booster
  EOF

  # include the parsed file as an emit value:
  $ cue import foo.yaml
  $ cat foo.cue
  {
      kind: Service
      name: booster
  }

  # include the parsed file at the root of the CUE file:
  $ cue import -f foo.yaml
  $ cat foo.cue
  kind: Service
  name: booster

  # include the import config at the mystuff path
  $ cue import -f -l '"mystuff"' foo.yaml
  $ cat foo.cue
  myStuff: {
      kind: Service
      name: booster
  }

  # append another object to the input file
  $ cat <<EOF >> foo.yaml
  ---
  kind: Deployment
  name: booster
  replicas: 1

  # base the path values on the input
  $ cue import -f -l 'strings.ToLower(kind)' -l name foo.yaml
  $ cat foo.cue
  service: booster: {
      kind: "Service"
      name: "booster"
  }

  # base the path values on the input and file name
  $ cue import -f --with-context -l 'path.Base(filename)' -l data.kind foo.yaml
  $ cat foo.cue
  "foo.yaml": Service: {
      kind: "Service"
      name: "booster"
  }

  "foo.yaml": Deployment: {
      kind:     "Deployment"
      name:     "booster
      replicas: 1
  }

  # include all files as list elements
  $ cue import -f -list -foo.yaml
  $ cat foo.cue
  [{
      kind: "Service"
      name: "booster"
  }, {
      kind:     "Deployment"
      name:     "booster
      replicas: 1
  }]

  # collate files with the same path into a list
  $ cue import -f -list -l 'strings.ToLower(kind)' foo.yaml
  $ cat foo.cue
  service: [{
      kind: "Service"
      name: "booster"
  }
  deployment: [{
      kind:     "Deployment"
      name:     "booster
      replicas: 1
  }]


Embedded data files

The --recursive or -R flag enables the parsing of fields that are string
representations of data formats themselves. A field that can be parsed is
replaced with a call encoding the data from a structured form that is placed
in a sibling field.

It is also possible to recursively hoist data formats:

Example:
  $ cat <<EOF > example.json
  "a": {
      "data": '{ "foo": 1, "bar": 2 }',
  }
  EOF

  $ cue import -R example.json
  $ cat example.cue
  import "encoding/json"

  a: {
      data: json.Encode(_data),
      _data = {
          foo: 1
          bar: 2
      }
  }
`,
		RunE: mkRunE(c, runImport),
	}

	addOutFlags(cmd.Flags(), false)
	addOrphanFlags(cmd.Flags())

	cmd.Flags().Bool(string(flagFiles), false, "split multiple entries into different files")
	cmd.Flags().BoolP(string(flagForce), "f", false, "force overwriting existing files")
	cmd.Flags().Bool(string(flagDryrun), false, "only run simulation")
	cmd.Flags().BoolP(string(flagRecursive), "R", false, "recursively parse string values")

	return cmd
}

// TODO: factor out rooting of orphaned files.

func runImport(cmd *Command, args []string) (err error) {
	c := &config{
		fileFilter:     `\.(json|yaml|yml|jsonl|ldjson)$`,
		interpretation: build.Auto,
		loadCfg:        &load.Config{DataFiles: true},
	}
	var mode string
	if len(args) >= 1 && !strings.ContainsAny(args[0], `/\:.`) {
		c.interpretation = ""
		mode = args[0]
		args = args[1:]
		switch mode {
		case "proto":
			c.fileFilter = `\.proto$`
		case "json":
			c.fileFilter = `\.(json|jsonl|ldjson)$`
		case "yaml":
			c.fileFilter = `\.(yaml|yml)$`
		case "text":
			c.fileFilter = `\.txt$`
		case "auto", "openapi", "jsonschema":
			c.interpretation = build.Interpretation(mode)
		case "data":
			// default mode for encoding/ no interpretation.
		default:
			return errors.Newf(token.NoPos, "unknown mode %q", mode)
		}
	}

	b, err := parseArgs(cmd, args, c)
	exitOnErr(cmd, err, true)

	switch mode {
	default:
		err = genericMode(cmd, b)
	case "proto":
		err = protoMode(b)
	}

	exitOnErr(cmd, err, true)
	return nil
}

func protoMode(b *buildPlan) error {
	var prev *build.Instance
	root := ""
	module := ""
	protoFiles := []*build.File{}

	for _, b := range b.insts {
		hasProto := false
		for _, f := range b.OrphanedFiles {
			if f.Encoding == "proto" {
				protoFiles = append(protoFiles, f)
				hasProto = true
			}
		}
		if !hasProto {
			continue
		}

		// check dirs, all must have same root.
		switch {
		case root != "":
			if b.Root != "" && root != b.Root {
				return errors.Newf(token.NoPos,
					"instances must have same root in proto mode; "+
						"found %q (%s) and %q (%s)",
					prev.Root, prev.DisplayPath, b.Root, b.DisplayPath)
			}
		case b.Root != "":
			root = b.Root
			module = b.Module
			prev = b
		}
	}

	c := &protobuf.Config{
		Root:    root,
		Module:  module,
		Paths:   b.encConfig.ProtoPath,
		PkgName: b.encConfig.PkgName,
	}
	if module != "" {
		// We only allow imports from packages within the module if an actual
		// module is allowed.
		c.Paths = append([]string{root}, c.Paths...)
	}
	p := protobuf.NewExtractor(c)
	for _, f := range protoFiles {
		_ = p.AddFile(f.Filename, f.Source)
	}

	files, err := p.Files()
	if err != nil {
		return err
	}

	modDir := ""
	if root != "" {
		modDir = internal.GenPath(root)
	}

	for _, f := range files {
		// Only write the cue.mod files if they don't exist or if -Rf is used.
		abs := f.Filename
		if !filepath.IsAbs(abs) {
			abs = filepath.Join(root, abs)
		}
		force := flagForce.Bool(b.cmd)
		if flagRecursive.Bool(b.cmd) && strings.HasPrefix(abs, modDir) {
			force = false
		}

		cueFile, err := getFilename(b, f, root, force)
		if cueFile == "" {
			return err
		}
		err = writeFile(b, f, cueFile)
		if err != nil {
			return err
		}
	}
	return nil
}

func genericMode(cmd *Command, b *buildPlan) error {
	pkgFlag := flagPackage.String(cmd)
	for _, pkg := range b.insts {
		pkgName := pkgFlag
		if pkgName == "" {
			pkgName = pkg.PkgName
		}
		// TODO: allow if there is a unique package name.
		if pkgName == "" && len(b.insts) > 1 {
			err := fmt.Errorf("must specify package name with the -p flag")
			exitOnErr(cmd, err, true)
		}
	}

	for _, f := range b.imported {
		err := handleFile(b, f)
		if err != nil {
			return err
		}
	}
	return nil
}

func getFilename(b *buildPlan, f *ast.File, root string, force bool) (filename string, err error) {
	cueFile := f.Filename
	if out := flagOutFile.String(b.cmd); out != "" {
		cueFile = out
	}

	if cueFile != "-" {
		switch _, err := os.Stat(cueFile); {
		case os.IsNotExist(err):
		case err == nil:
			if !force {
				// TODO: mimic old behavior: write to stderr, but do not exit
				// with error code. Consider what is best to do here.
				stderr := b.cmd.Command.OutOrStderr()
				if root != "" {
					cueFile, _ = filepath.Rel(root, cueFile)
				}
				fmt.Fprintf(stderr, "Skipping file %q: already exists.\n",
					filepath.ToSlash(cueFile))
				if strings.HasPrefix(cueFile, "cue.mod") {
					fmt.Fprintln(stderr, "Use -Rf to override.")
				} else {
					fmt.Fprintln(stderr, "Use -f to override.")
				}
				return "", nil
			}
		default:
			return "", fmt.Errorf("error creating file: %v", err)
		}
	}
	return cueFile, nil
}

func handleFile(b *buildPlan, f *ast.File) (err error) {
	// TODO: fill out root.
	cueFile, err := getFilename(b, f, "", flagForce.Bool(b.cmd))
	if cueFile == "" {
		return err
	}

	if flagRecursive.Bool(b.cmd) {
		h := hoister{fields: map[string]bool{}}
		h.hoist(f)
	}

	return writeFile(b, f, cueFile)
}

func writeFile(p *buildPlan, f *ast.File, cueFile string) error {
	b, err := format.Node(f, format.Simplify())
	if err != nil {
		return fmt.Errorf("error formatting file: %v", err)
	}

	if cueFile == "-" {
		_, err := p.cmd.OutOrStdout().Write(b)
		return err
	}
	_ = os.MkdirAll(filepath.Dir(cueFile), 0755)
	return ioutil.WriteFile(cueFile, b, 0644)
}

type hoister struct {
	fields map[string]bool
}

func (h *hoister) hoist(f *ast.File) {
	ast.Walk(f, nil, func(n ast.Node) {
		name := ""
		switch x := n.(type) {
		case *ast.Field:
			name, _, _ = ast.LabelName(x.Label)
		case *ast.Alias:
			name = x.Ident.Name
		case *ast.LetClause:
			name = x.Ident.Name
		}
		if name != "" {
			h.fields[name] = true
		}
	})

	_ = astutil.Apply(f, func(c astutil.Cursor) bool {
		n := c.Node()
		switch n.(type) {
		case *ast.Comprehension:
			return false
		}
		return true

	}, func(c astutil.Cursor) bool {
		switch f := c.Node().(type) {
		case *ast.Field:
			name, _, _ := ast.LabelName(f.Label)
			if name == "" {
				return false
			}

			lit, ok := f.Value.(*ast.BasicLit)
			if !ok || lit.Kind != token.STRING {
				return false
			}

			str, err := literal.Unquote(lit.Value)
			if err != nil {
				return false
			}

			expr, enc := tryParse(str)
			if expr == nil {
				return false
			}

			pkg := c.Import("encoding/" + enc)
			if pkg == nil {
				return false
			}

			// found a replacable string
			dataField := h.uniqueName(name, "_", "cue_")

			f.Value = ast.NewCall(
				ast.NewSel(pkg, "Marshal"),
				ast.NewIdent(dataField))

			// TODO: use definitions instead
			c.InsertAfter(astutil.ApplyRecursively(&ast.LetClause{
				Ident: ast.NewIdent(dataField),
				Expr:  expr,
			}))
		}
		return true
	})
}

func tryParse(str string) (s ast.Expr, pkg string) {
	b := []byte(str)
	if json.Valid(b) {
		expr, err := parser.ParseExpr("", b)
		if err != nil {
			// TODO: report error
			return nil, ""
		}
		switch expr.(type) {
		case *ast.StructLit, *ast.ListLit:
		default:
			return nil, ""
		}
		return expr, "json"
	}

	if expr, err := yaml.Unmarshal("", b); err == nil {
		switch expr.(type) {
		case *ast.StructLit, *ast.ListLit:
		default:
			return nil, ""
		}
		return expr, "yaml"
	}

	return nil, ""
}

func (h *hoister) uniqueName(base, prefix, typ string) string {
	base = strings.Map(func(r rune) rune {
		if unicode.In(r, unicode.L, unicode.N) {
			return r
		}
		return '_'
	}, base)

	name := prefix + typ + base
	for {
		if !h.fields[name] {
			h.fields[name] = true
			return name
		}
		name = prefix + typ + base
		typ += "x"
	}
}
