/*
 * Copyright 2019-present Ciena Corporation
 *
 * 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 format

import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"text/tabwriter"
	"text/template"
	"text/template/parse"
)

var nameFinder = regexp.MustCompile(`\.([\._A-Za-z0-9]*)}}`)

type Format string

/* TrimAndPad
 *
 * Modify `s` so that it is exactly `l` characters long, removing
 * characters from the end, or adding spaces as necessary.
 */

func TrimAndPad(s string, l int) string {
	// TODO: support right justification if a negative number is passed
	if len(s) > l {
		s = s[:l]
	}
	return s + strings.Repeat(" ", l-len(s))
}

/* GetHeaderString
 *
 * From a template, extract the set of column names.
 */

func GetHeaderString(tmpl *template.Template, nameLimit int) string {
	var header string
	for _, n := range tmpl.Tree.Root.Nodes {
		switch n.Type() {
		case parse.NodeText:
			header += n.String()
		case parse.NodeString:
			header += n.String()
		case parse.NodeAction:
			found := nameFinder.FindStringSubmatch(n.String())
			if len(found) == 2 {
				if nameLimit > 0 {
					parts := strings.Split(found[1], ".")
					start := len(parts) - nameLimit
					if start < 0 {
						start = 0
					}
					header += strings.ToUpper(strings.Join(parts[start:], "."))
				} else {
					header += strings.ToUpper(found[1])
				}
			}
		}
	}
	return header
}

func (f Format) IsTable() bool {
	return strings.HasPrefix(string(f), "table")
}

func (f Format) Execute(writer io.Writer, withHeaders bool, nameLimit int, data interface{}) error {
	var tabWriter *tabwriter.Writer = nil
	format := f

	if f.IsTable() {
		tabWriter = tabwriter.NewWriter(writer, 0, 4, 4, ' ', 0)
		format = Format(strings.TrimPrefix(string(f), "table"))
	}

	tmpl, err := template.New("output").Parse(string(format))
	if err != nil {
		return err
	}

	if f.IsTable() && withHeaders {
		header := GetHeaderString(tmpl, nameLimit)

		if _, err = tabWriter.Write([]byte(header)); err != nil {
			return err
		}
		if _, err = tabWriter.Write([]byte("\n")); err != nil {
			return err
		}

		slice := reflect.ValueOf(data)
		if slice.Kind() == reflect.Slice {
			for i := 0; i < slice.Len(); i++ {
				if err = tmpl.Execute(tabWriter, slice.Index(i).Interface()); err != nil {
					return err
				}
				if _, err = tabWriter.Write([]byte("\n")); err != nil {
					return err
				}
			}
		} else {
			if err = tmpl.Execute(tabWriter, data); err != nil {
				return err
			}
			if _, err = tabWriter.Write([]byte("\n")); err != nil {
				return err
			}
		}
		tabWriter.Flush()
		return nil
	}

	slice := reflect.ValueOf(data)
	if slice.Kind() == reflect.Slice {
		for i := 0; i < slice.Len(); i++ {
			if err = tmpl.Execute(writer, slice.Index(i).Interface()); err != nil {
				return err
			}
			if _, err = writer.Write([]byte("\n")); err != nil {
				return err
			}
		}
	} else {
		if err = tmpl.Execute(writer, data); err != nil {
			return err
		}
		if _, err = writer.Write([]byte("\n")); err != nil {
			return err
		}
	}
	return nil

}

/*
 * ExecuteFixedWidth
 *
 * Formats a table row using a set of fixed column widths. Used for streaming
 * output where column widths cannot be automatically determined because only
 * one line of the output is available at a time.
 *
 * Assumes the format uses tab as a field delimiter.
 *
 * columnWidths: struct that contains column widths
 * header: If true return the header. If false then evaluate data and return data.
 * data: Data to evaluate
 */

func (f Format) ExecuteFixedWidth(columnWidths interface{}, header bool, data interface{}) (string, error) {
	if !f.IsTable() {
		return "", errors.New("Fixed width is only available on table format")
	}

	outputAs := strings.TrimPrefix(string(f), "table")
	tmpl, err := template.New("output").Parse(string(outputAs))
	if err != nil {
		return "", fmt.Errorf("Failed to parse template: %v", err)
	}

	var buf bytes.Buffer
	var tabSepOutput string

	if header {
		// Caller wants the table header.
		tabSepOutput = GetHeaderString(tmpl, 1)
	} else {
		// Caller wants the data.
		err = tmpl.Execute(&buf, data)
		if err != nil {
			return "", fmt.Errorf("Failed to execute template: %v", err)
		}
		tabSepOutput = buf.String()
	}

	// Extract the column width constants by running the template on the
	// columnWidth structure. This will cause text.template to split the
	// column widths exactly like it did the output (i.e. separated by
	// tab characters)
	buf.Reset()
	err = tmpl.Execute(&buf, columnWidths)
	if err != nil {
		return "", fmt.Errorf("Failed to execute template on widths: %v", err)
	}
	tabSepWidth := buf.String()

	// Loop through the fields and widths, printing each field to the
	// preset width.
	output := ""
	outParts := strings.Split(tabSepOutput, "\t")
	widthParts := strings.Split(tabSepWidth, "\t")
	for i, outPart := range outParts {
		width, err := strconv.Atoi(widthParts[i])
		if err != nil {
			return "", fmt.Errorf("Failed to parse width %s: %v", widthParts[i], err)
		}
		output = output + TrimAndPad(outPart, width) + " "
	}

	// remove any trailing spaces
	output = strings.TrimRight(output, " ")

	return output, nil
}
