package parts

import (
	
	
	

	
	

	
)

// This file contains the implementation of the Part interface backed by a Parquet Buffer.
type parquetPart struct {
	basePart

	ref *atomic.Int32
	buf *dynparquet.SerializedBuffer
}

func ( *parquetPart) () arrow.Record {
	return nil
}

func ( *parquetPart) () { .ref.Add(1) }

func ( *parquetPart) () {
	 := .ref.Add(-1)
	if  <= 0 && .release != nil {
		.release()
	}
}

func ( *parquetPart) ( io.Writer) error {
	,  := .AsSerializedBuffer(nil)
	if  != nil {
		return 
	}

	 := .ParquetFile()
	_,  = io.Copy(, io.NewSectionReader(, 0, .Size()))
	return 
}

func ( *parquetPart) ( *dynparquet.Schema,  dynparquet.ParquetWriter) error {
	return fmt.Errorf("not a record part")
}

func ( *parquetPart) ( *dynparquet.Schema) (*dynparquet.SerializedBuffer, error) {
	return .buf, nil
}

func ( uint64,  *dynparquet.SerializedBuffer,  ...Option) Part {
	 := &parquetPart{
		basePart: basePart{
			tx: ,
		},
		ref: &atomic.Int32{},
		buf: ,
	}

	for ,  := range  {
		(&.basePart)
	}

	.ref.Add(1)
	return 
}

func ( *parquetPart) () int64 {
	return .buf.NumRows()
}

func ( *parquetPart) () int64 {
	return .buf.ParquetFile().Size()
}

// Least returns the least row  in the part.
func ( *parquetPart) () (*dynparquet.DynamicRow, error) {
	if .minRow != nil {
		return .minRow, nil
	}

	,  := minRow(.buf)
	if  != nil {
		return nil, 
	}

	.minRow = 
	return .minRow, nil
}

func ( *parquetPart) () (*dynparquet.DynamicRow, error) {
	if .maxRow != nil {
		return .maxRow, nil
	}

	,  := maxRow(.buf)
	if  != nil {
		return nil, 
	}
	.maxRow = 
	return .maxRow, nil
}

func ( *parquetPart) ( *dynparquet.Schema,  Part) (bool, error) {
	,  := .Least()
	if  != nil {
		return false, 
	}
	,  := .Most()
	if  != nil {
		return false, 
	}
	,  := .Least()
	if  != nil {
		return false, 
	}
	,  := .Most()
	if  != nil {
		return false, 
	}

	return .Cmp(, ) <= 0 && .Cmp(, ) <= 0, nil
}

func maxRow( *dynparquet.SerializedBuffer) (*dynparquet.DynamicRow, error) {
	 := &dynparquet.DynamicRows{Rows: make([]parquet.Row, 1)}
	 := .DynamicRowGroup(.NumRowGroups() - 1)
	 := .DynamicRows()
	defer .Close()

	if  := .SeekToRow(.NumRows() - 1);  != nil {
		return nil, fmt.Errorf("seek to last row of part: %w", )
	}

	if ,  := .ReadRows();  != nil {
		return nil, fmt.Errorf("read last row of part: %w", )
	} else if  != 1 {
		return nil, fmt.Errorf("expected to read exactly 1 row, but read %d", )
	}

	// Copy here so that this reference does not prevent the decompressed page
	// from being GCed.
	return .GetCopy(0), nil
}

func minRow( *dynparquet.SerializedBuffer) (*dynparquet.DynamicRow, error) {
	 := &dynparquet.DynamicRows{Rows: make([]parquet.Row, 1)}
	 := .DynamicRowGroup(0).DynamicRows()
	defer .Close()

	if ,  := .ReadRows();  != nil {
		return nil, fmt.Errorf("read first row of part: %w", )
	} else if  != 1 {
		return nil, fmt.Errorf("expected to read exactly 1 row, but read %d", )
	}

	// Copy here so that this reference does not prevent the decompressed page
	// from being GCed.
	return .GetCopy(0), nil
}