package dynparquet

import (
	
	
	

	
)

const (
	DynamicColumnsKey = "dynamic_columns"
)

var ErrNoDynamicColumns = errors.New("no dynamic columns metadata found, it must be present")

type SerializedBuffer struct {
	f       *parquet.File
	dynCols map[string][]string
	fields  []parquet.Field
}

func ( []byte) (*SerializedBuffer, error) {
	,  := parquet.OpenFile(bytes.NewReader(), int64(len()))
	if  != nil {
		return nil, fmt.Errorf("error opening file from buffer: %w", )
	}

	return NewSerializedBuffer()
}

func ( *parquet.File) (*SerializedBuffer, error) {
	,  := .Lookup(DynamicColumnsKey)
	if ! {
		return nil, ErrNoDynamicColumns
	}

	,  := deserializeDynamicColumns()
	if  != nil {
		return nil, fmt.Errorf("deserialize dynamic columns metadata %q: %w", , )
	}

	return &SerializedBuffer{
		f:       ,
		dynCols: ,
		fields:  .Schema().Fields(),
	}, nil
}

func ( *SerializedBuffer) () *parquet.GenericReader[any] {
	return parquet.NewGenericReader[any](.ParquetFile())
}

func ( *SerializedBuffer) () *parquet.File {
	return .f
}

func ( *SerializedBuffer) () int64 {
	return .ParquetFile().NumRows()
}

func ( *SerializedBuffer) () int {
	return len(.f.RowGroups())
}

func ( *SerializedBuffer) () DynamicRowReader {
	 := .f.RowGroups()
	 := make([]DynamicRowGroup, len())
	for ,  := range  {
		[] = .newDynamicRowGroup()
	}
	return Concat(.fields, ...).DynamicRows()
}

func ( *SerializedBuffer) () string {
	 := .NumRowGroups()
	 := .NumRows()
	 := newPrettyWriter()
	_, _ = fmt.Fprintf(, "num row groups: %d\tnum rows: %d\n", , )
	for  := 0;  < ; ++ {
		_, _ = fmt.Fprint(, "---\n")
		.writePrettyRowGroup(.DynamicRowGroup())
	}
	_ = .Flush()

	return .String()
}

type serializedRowGroup struct {
	parquet.RowGroup
	dynCols map[string][]string
	fields  []parquet.Field
}

func ( *SerializedBuffer) ( int) DynamicRowGroup {
	return .newDynamicRowGroup(.f.RowGroups()[])
}

// MultiDynamicRowGroup returns all the row groups wrapped in a single multi
// row group.
func ( *SerializedBuffer) () DynamicRowGroup {
	return .newDynamicRowGroup(parquet.MultiRowGroup(.f.RowGroups()...))
}

func ( *SerializedBuffer) ( parquet.RowGroup) DynamicRowGroup {
	return &serializedRowGroup{
		RowGroup: ,
		dynCols:  .dynCols,
		fields:   .fields,
	}
}

func ( *serializedRowGroup) () string {
	return prettyRowGroup()
}

func ( *serializedRowGroup) () map[string][]string {
	return .dynCols
}

func ( *serializedRowGroup) () DynamicRowReader {
	return newDynamicRowGroupReader(, .fields)
}

func ( *SerializedBuffer) () map[string][]string {
	return .dynCols
}