package Marshal

import (
	"fmt"
	"testing"

	. "github.com/xitongsys/parquet-go/SchemaHandler"
)

type Student struct {
	Name    string               `parquet:"name=name, type=UTF8"`
	Age     int32                `parquet:"name=age, type=INT32"`
	Weight  *int32               `parquet:"name=weight, type=INT32"`
	Classes *map[string][]*Class `parquet:"name=classes, keytype=UTF8"`
}

type Class struct {
	Name     string   `parquet:"name=name, type=UTF8"`
	ID       *int64   `parquet:"name=id, type=INT64"`
	Required []string `parquet:"name=required, type=UTF8"`
}

func (c Class) String() string {
	id := "nil"
	if c.ID != nil {
		id = fmt.Sprintf("%d", *c.ID)
	}
	res := fmt.Sprintf("{Name:%s, ID:%v, Required:%s}", c.Name, id, fmt.Sprint(c.Required))
	return res
}

func (s Student) String() string {
	weight := "nil"
	if s.Weight != nil {
		weight = fmt.Sprintf("%d", *s.Weight)
	}

	cs := "{"
	for key, classes := range *s.Classes {
		s := string(key) + ":["
		for _, class := range classes {
			s += (*class).String() + ","
		}
		s += "]"
		cs += s
	}
	cs += "}"
	res := fmt.Sprintf("{Name:%s, Age:%d, Weight:%s, Classes:%s}", s.Name, s.Age, weight, cs)
	return res
}

func TestMarshalUnmarshal(t *testing.T) {
	schemaHandler, _ := NewSchemaHandlerFromStruct(new(Student))
	fmt.Println("SchemaHandler Finished")

	math01ID := int64(1)
	math01 := Class{
		Name:     "Math1",
		ID:       &math01ID,
		Required: make([]string, 0),
	}

	math02ID := int64(2)
	math02 := Class{
		Name:     "Math2",
		ID:       &math02ID,
		Required: make([]string, 0),
	}
	math02.Required = append(math02.Required, "Math01")

	physics := Class{
		Name:     "Physics",
		ID:       nil,
		Required: make([]string, 0),
	}
	physics.Required = append(physics.Required, "Math01", "Math02")

	weight01 := int32(60)
	stu01Class := make(map[string][]*Class)
	stu01Class["Science"] = make([]*Class, 0)
	stu01Class["Science"] = append(stu01Class["Science"], &math01, &math02)
	stu01 := Student{
		Name:    "zxt",
		Age:     18,
		Weight:  &weight01,
		Classes: &stu01Class,
	}

	stu02Class := make(map[string][]*Class)
	stu02Class["Science"] = make([]*Class, 0)
	stu02Class["Science"] = append(stu02Class["Science"], &physics)
	stu02 := Student{
		Name:    "tong",
		Age:     29,
		Weight:  nil,
		Classes: &stu02Class,
	}

	stus := make([]interface{}, 0)
	stus = append(stus, stu01, stu02)

	src, _ := Marshal(stus, 0, len(stus), schemaHandler)
	fmt.Println("Marshal Finished")

	for name, table := range *src {
		fmt.Println(name)
		fmt.Println("Val: ", table.Values)
		fmt.Println("RL: ", table.RepetitionLevels)
		fmt.Println("DL: ", table.DefinitionLevels)
	}

	dst := make([]Student, 0)
	Unmarshal(src, 0, len(stus), &dst, schemaHandler)

	s0 := fmt.Sprint(stus)
	s1 := fmt.Sprint(dst)
	if s0 != s1 {
		t.Errorf("Fail expect %s, get %s", s0, s1)
	}

}
