<commit_before>package format

import (
	"fmt"
	"github.com/ingrammicro/concerto/utils"
	"io"
	"reflect"
	"strings"
	"text/tabwriter"

	log "github.com/Sirupsen/logrus"
)

// TextFormatter prints items and lists
type TextFormatter struct {
	output io.Writer
}

// NewTextFormatter creates a new TextFormatter
func NewTextFormatter(out io.Writer) *TextFormatter {
	log.Debug("Creating Text formatter")

	return &TextFormatter{
		output: out,
	}
}

func (f *TextFormatter) printItemAux(w *tabwriter.Writer, item interface{}) error {
	log.Debug("printItemAux")

	it := reflect.ValueOf(item)
	for i := 0; i < it.NumField(); i++ {
		showTags := strings.Split(it.Type().Field(i).Tag.Get("show"), ",")
		if !utils.Contains(showTags, "noshow") {
			switch it.Field(i).Type().String() {
			case "json.RawMessage":
				fmt.Fprintln(w, fmt.Sprintf("%s:\t%s", it.Type().Field(i).Tag.Get("header"), it.Field(i).Interface()))
			case "*json.RawMessage":
				fmt.Fprintln(w, fmt.Sprintf("%s:\t%s", it.Type().Field(i).Tag.Get("header"), it.Field(i).Elem()))
			default:
				if it.Field(i).Kind() == reflect.Struct {
					f.printItemAux(w, it.Field(i).Interface())
				} else {
					fmt.Fprintln(w, fmt.Sprintf("%s:\t%+v", it.Type().Field(i).Tag.Get("header"), it.Field(i).Interface()))
				}
			}
		}
	}
	return nil
}

// PrintItem prints item
func (f *TextFormatter) PrintItem(item interface{}) error {
	log.Debug("PrintItem")

	w := tabwriter.NewWriter(f.output, 15, 1, 3, ' ', 0)
	f.printItemAux(w, item)
	w.Flush()

	return nil
}

func (f *TextFormatter) printListHeadersAux(w *tabwriter.Writer, t reflect.Type) {
	log.Debug("printListHeadersAux")

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Type.Kind() == reflect.Struct {
			f.printListHeadersAux(w, field.Type)
		}

		showTags := strings.Split(field.Tag.Get("show"), ",")
		if !utils.Contains(showTags, "nolist") {
			fmt.Fprint(w, fmt.Sprintf("%+v\t", field.Tag.Get("header")))
		}
	}
}

func (f *TextFormatter) printListBodyAux(w *tabwriter.Writer, t reflect.Value) {
	log.Debug("printListBodyAux")

	for i := 0; i < t.NumField(); i++ {
		showTags := strings.Split(t.Type().Field(i).Tag.Get("show"), ",")
		if !utils.Contains(showTags, "nolist") {
			field := t.Field(i)
			switch field.Type().String() {
			case "json.RawMessage":<commit_msg>Fix time text formatter (issue #92)<commit_after>package format

import (
	"fmt"
	"github.com/ingrammicro/concerto/utils"
	"io"
	"reflect"
	"strings"
	"text/tabwriter"

	log "github.com/Sirupsen/logrus"
)

// TextFormatter prints items and lists
type TextFormatter struct {
	output io.Writer
}

// NewTextFormatter creates a new TextFormatter
func NewTextFormatter(out io.Writer) *TextFormatter {
	log.Debug("Creating Text formatter")

	return &TextFormatter{
		output: out,
	}
}

func (f *TextFormatter) printItemAux(w *tabwriter.Writer, item interface{}) error {
	log.Debug("printItemAux")

	it := reflect.ValueOf(item)
	for i := 0; i < it.NumField(); i++ {
		showTags := strings.Split(it.Type().Field(i).Tag.Get("show"), ",")
		if !utils.Contains(showTags, "noshow") {
			switch it.Field(i).Type().String() {
			case "time.Time":
				fmt.Fprintln(w, fmt.Sprintf("%s:\t%+v", it.Type().Field(i).Tag.Get("header"), it.Field(i).Interface()))
			case "json.RawMessage":
				fmt.Fprintln(w, fmt.Sprintf("%s:\t%s", it.Type().Field(i).Tag.Get("header"), it.Field(i).Interface()))
			case "*json.RawMessage":
				fmt.Fprintln(w, fmt.Sprintf("%s:\t%s", it.Type().Field(i).Tag.Get("header"), it.Field(i).Elem()))
			default:
				if it.Field(i).Kind() == reflect.Struct {
					f.printItemAux(w, it.Field(i).Interface())
				} else {
					fmt.Fprintln(w, fmt.Sprintf("%s:\t%+v", it.Type().Field(i).Tag.Get("header"), it.Field(i).Interface()))
				}
			}
		}
	}
	return nil
}

// PrintItem prints item
func (f *TextFormatter) PrintItem(item interface{}) error {
	log.Debug("PrintItem")

	w := tabwriter.NewWriter(f.output, 15, 1, 3, ' ', 0)
	f.printItemAux(w, item)
	w.Flush()

	return nil
}

func (f *TextFormatter) printListHeadersAux(w *tabwriter.Writer, t reflect.Type) {
	log.Debug("printListHeadersAux")

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Type.Kind() == reflect.Struct {
			f.printListHeadersAux(w, field.Type)
		}

		showTags := strings.Split(field.Tag.Get("show"), ",")
		if !utils.Contains(showTags, "nolist") {
			fmt.Fprint(w, fmt.Sprintf("%+v\t", field.Tag.Get("header")))
		}
	}
}

func (f *TextFormatter) printListBodyAux(w *tabwriter.Writer, t reflect.Value) {
	log.Debug("printListBodyAux")

	for i := 0; i < t.NumField(); i++ {
		showTags := strings.Split(t.Type().Field(i).Tag.Get("show"), ",")
		if !utils.Contains(showTags, "nolist") {
			field := t.Field(i)
			switch field.Type().String() {
			case "time.Time":
				fmt.Fprint(w, fmt.Sprintf("%+v\t", field.Interface()))
			case "json.RawMessage":
{'fraction_non_alphanumeric': 0.19983535706935585, 'fraction_numerical': 0.003704465939493723, 'mean_word_length': 4.1923076923076925, 'pattern_counts': {'":': 8, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1758016', 'n_tokens_mistral': 1967, 'n_tokens_neox': 1802, 'n_words': 337}