/*
Copyright 2015 The Kubernetes 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 (
	"bytes"
	"fmt"
	"go/ast"
	"go/doc"
	"go/parser"
	"go/token"
	"io"
	"reflect"
	"strings"
)

// Pair of strings. We keed the name of fields and the doc
type Pair struct {
	Name, Doc string
}

// KubeTypes is an array to represent all available types in a parsed file. [0] is for the type itself
type KubeTypes []Pair

func astFrom(filePath string) *doc.Package {
	fset := token.NewFileSet()
	m := make(map[string]*ast.File)

	f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	m[filePath] = f
	apkg, _ := ast.NewPackage(fset, m, nil, nil)

	return doc.New(apkg, "", 0)
}

func fmtRawDoc(rawDoc string) string {
	var buffer bytes.Buffer
	delPrevChar := func() {
		if buffer.Len() > 0 {
			buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n"
		}
	}

	// Ignore all lines after ---
	rawDoc = strings.Split(rawDoc, "---")[0]

	for _, line := range strings.Split(rawDoc, "\n") {
		line = strings.TrimRight(line, " ")
		leading := strings.TrimLeft(line, " ")
		switch {
		case len(line) == 0: // Keep paragraphs
			delPrevChar()
			buffer.WriteString("\n\n")
		case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs
		case strings.HasPrefix(leading, "+"): // Ignore instructions to the generators
		default:
			if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
				delPrevChar()
				line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..."
			} else {
				line += " "
			}
			buffer.WriteString(line)
		}
	}

	postDoc := strings.TrimRight(buffer.String(), "\n")
	postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to "
	postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape "
	postDoc = strings.Replace(postDoc, "\n", "\\n", -1)
	postDoc = strings.Replace(postDoc, "\t", "\\t", -1)

	return postDoc
}

// fieldName returns the name of the field as it should appear in JSON format
// "-" indicates that this field is not part of the JSON representation
func fieldName(field *ast.Field) string {
	jsonTag := ""
	if field.Tag != nil {
		jsonTag = reflect.StructTag(field.Tag.Value[1 : len(field.Tag.Value)-1]).Get("json") // Delete first and last quotation
		if strings.Contains(jsonTag, "inline") {
			return "-"
		}
	}

	jsonTag = strings.Split(jsonTag, ",")[0] // This can return "-"
	if jsonTag == "" {
		if field.Names != nil {
			return field.Names[0].Name
		}
		return field.Type.(*ast.Ident).Name
	}
	return jsonTag
}

// A buffer of lines that will be written.
type bufferedLine struct {
	line        string
	indentation int
}

type buffer struct {
	lines []bufferedLine
}

func newBuffer() *buffer {
	return &buffer{
		lines: make([]bufferedLine, 0),
	}
}

func (b *buffer) addLine(line string, indent int) {
	b.lines = append(b.lines, bufferedLine{line, indent})
}

func (b *buffer) flushLines(w io.Writer) error {
	for _, line := range b.lines {
		indentation := strings.Repeat("\t", line.indentation)
		fullLine := fmt.Sprintf("%s%s", indentation, line.line)
		if _, err := io.WriteString(w, fullLine); err != nil {
			return err
		}
	}
	return nil
}

func writeFuncHeader(b *buffer, structName string, indent int) {
	s := fmt.Sprintf("var map_%s = map[string]string {\n", structName)
	b.addLine(s, indent)
}

func writeFuncFooter(b *buffer, structName string, indent int) {
	b.addLine("}\n", indent) // Closes the map definition

	s := fmt.Sprintf("func (%s) SwaggerDoc() map[string]string {\n", structName)
	b.addLine(s, indent)
	s = fmt.Sprintf("return map_%s\n", structName)
	b.addLine(s, indent+1)
	b.addLine("}\n", indent) // Closes the function definition
}

func writeMapBody(b *buffer, kubeType []Pair, indent int) {
	format := "\"%s\": \"%s\",\n"
	for _, pair := range kubeType {
		s := fmt.Sprintf(format, pair.Name, pair.Doc)
		b.addLine(s, indent+2)
	}
}

// ParseDocumentationFrom gets all types' documentation and returns them as an
// array. Each type is again represented as an array (we have to use arrays as we
// need to be sure for the order of the fields). This function returns fields and
// struct definitions that have no documentation as {name, ""}.
func ParseDocumentationFrom(src string) []KubeTypes {
	var docForTypes []KubeTypes

	pkg := astFrom(src)

	for _, kubType := range pkg.Types {
		if structType, ok := kubType.Decl.Specs[0].(*ast.TypeSpec).Type.(*ast.StructType); ok {
			var ks KubeTypes
			ks = append(ks, Pair{kubType.Name, fmtRawDoc(kubType.Doc)})

			for _, field := range structType.Fields.List {
				if n := fieldName(field); n != "-" {
					fieldDoc := fmtRawDoc(field.Doc.Text())
					ks = append(ks, Pair{n, fieldDoc})
				}
			}
			docForTypes = append(docForTypes, ks)
		}
	}

	return docForTypes
}

// WriteSwaggerDocFunc writes a declaration of a function as a string. This function is used in
// Swagger as a documentation source for structs and theirs fields
func WriteSwaggerDocFunc(kubeTypes []KubeTypes, w io.Writer) error {
	for _, kubeType := range kubeTypes {
		structName := kubeType[0].Name
		kubeType[0].Name = ""

		// Ignore empty documentation
		docfulTypes := make(KubeTypes, 0, len(kubeType))
		for _, pair := range kubeType {
			if pair.Doc != "" {
				docfulTypes = append(docfulTypes, pair)
			}
		}

		if len(docfulTypes) == 0 {
			continue // If no fields and the struct have documentation, skip the function definition
		}

		indent := 0
		buffer := newBuffer()

		writeFuncHeader(buffer, structName, indent)
		writeMapBody(buffer, docfulTypes, indent)
		writeFuncFooter(buffer, structName, indent)
		buffer.addLine("\n", 0)

		if err := buffer.flushLines(w); err != nil {
			return err
		}
	}

	return nil
}

// VerifySwaggerDocsExist writes in a io.Writer a list of structs and fields that
// are missing of documentation.
func VerifySwaggerDocsExist(kubeTypes []KubeTypes, w io.Writer) (int, error) {
	missingDocs := 0
	buffer := newBuffer()

	for _, kubeType := range kubeTypes {
		structName := kubeType[0].Name
		if kubeType[0].Doc == "" {
			format := "Missing documentation for the struct itself: %s\n"
			s := fmt.Sprintf(format, structName)
			buffer.addLine(s, 0)
			missingDocs++
		}
		kubeType = kubeType[1:] // Skip struct definition

		for _, pair := range kubeType { // Iterate only the fields
			if pair.Doc == "" {
				format := "In struct: %s, field documentation is missing: %s\n"
				s := fmt.Sprintf(format, structName, pair.Name)
				buffer.addLine(s, 0)
				missingDocs++
			}
		}
	}

	if err := buffer.flushLines(w); err != nil {
		return -1, err
	}
	return missingDocs, nil
}
