// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 array_test

import (
	"bytes"
	"testing"

	"github.com/apache/arrow-go/v18/arrow"
	"github.com/apache/arrow-go/v18/arrow/array"
	"github.com/apache/arrow-go/v18/arrow/memory"
	"github.com/stretchr/testify/assert"
)

func TestBinaryBuilder(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewBinaryBuilder(mem, arrow.BinaryTypes.Binary)

	exp := [][]byte{[]byte("foo"), []byte("bar"), nil, []byte("sydney"), []byte("cameron")}
	for _, v := range exp {
		if v == nil {
			ab.AppendNull()
		} else {
			ab.Append(v)
		}
	}

	assert.Equal(t, len(exp), ab.Len(), "unexpected Len()")
	assert.Equal(t, 1, ab.NullN(), "unexpected NullN()")

	for i, v := range exp {
		if v == nil {
			v = []byte{}
		}
		assert.Equal(t, v, ab.Value(i), "unexpected BinaryArrayBuilder.Value(%d)", i)
	}
	// Zm9v is foo in base64
	assert.NoError(t, ab.AppendValueFromString("Zm9v"))

	ar := ab.NewBinaryArray()
	assert.Equal(t, "Zm9v", ar.ValueStr(5))

	ab.Release()
	ar.Release()

	// check state of builder after NewBinaryArray
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewBinaryArray did not reset state")
}

func TestBinaryBuilder_ReserveData(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewBinaryBuilder(mem, arrow.BinaryTypes.Binary)

	// call ReserveData and ensure the capacity doesn't change
	// when appending entries until that count.
	ab.ReserveData(256)
	expCap := ab.DataCap()
	for i := 0; i < 256/8; i++ {
		ab.Append(bytes.Repeat([]byte("a"), 8))
	}
	assert.Equal(t, expCap, ab.DataCap(), "unexpected BinaryArrayBuilder.DataCap()")

	ar := ab.NewBinaryArray()
	ab.Release()
	ar.Release()

	// check state of builder after NewBinaryArray
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewBinaryArray did not reset state")
}

func TestBinaryBuilderLarge(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewBinaryBuilder(mem, arrow.BinaryTypes.LargeBinary)

	exp := [][]byte{[]byte("foo"), []byte("bar"), nil, []byte("sydney"), []byte("cameron")}
	for _, v := range exp {
		if v == nil {
			ab.AppendNull()
		} else {
			ab.Append(v)
		}
	}

	assert.Equal(t, len(exp), ab.Len(), "unexpected Len()")
	assert.Equal(t, 1, ab.NullN(), "unexpected NullN()")

	for i, v := range exp {
		if v == nil {
			v = []byte{}
		}
		assert.Equal(t, v, ab.Value(i), "unexpected BinaryArrayBuilder.Value(%d)", i)
	}

	ar := ab.NewLargeBinaryArray()
	ab.Release()
	ar.Release()

	// check state of builder after NewBinaryArray
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewBinaryArray did not reset state")
}

func TestBinaryBuilderLarge_ReserveData(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewBinaryBuilder(mem, arrow.BinaryTypes.LargeBinary)

	// call ReserveData and ensure the capacity doesn't change
	// when appending entries until that count.
	ab.ReserveData(256)
	expCap := ab.DataCap()
	for i := 0; i < 256/8; i++ {
		ab.Append(bytes.Repeat([]byte("a"), 8))
	}
	assert.Equal(t, expCap, ab.DataCap(), "unexpected BinaryArrayBuilder.DataCap()")

	ar := ab.NewLargeBinaryArray()
	ab.Release()
	ar.Release()

	// check state of builder after NewBinaryArray
	assert.Zero(t, ab.Len(), "unexpected ArrayBuilder.Len(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.Cap(), "unexpected ArrayBuilder.Cap(), NewBinaryArray did not reset state")
	assert.Zero(t, ab.NullN(), "unexpected ArrayBuilder.NullN(), NewBinaryArray did not reset state")
}

// TestBinaryBuilder_AllEmptyValues reproduces issue #625
// When all values in a binary column are empty, they should be treated as
// empty byte slices, not as NULL values
func TestBinaryBuilder_AllEmptyValues(t *testing.T) {
	mem := memory.NewCheckedAllocator(memory.NewGoAllocator())
	defer mem.AssertSize(t, 0)

	ab := array.NewBinaryBuilder(mem, arrow.BinaryTypes.Binary)
	defer ab.Release()

	// Case 1: Empty + Data - this works correctly
	ab.Append([]byte(""))
	ab.Append([]byte(""))
	ab.Append([]byte("SGVsbG8sIFdvcmxkIQ=="))

	ar := ab.NewBinaryArray()
	defer ar.Release()

	assert.Equal(t, 3, ar.Len())
	assert.Equal(t, 0, ar.NullN())

	// First two should be empty slices, not nil
	for i := 0; i < 2; i++ {
		assert.False(t, ar.IsNull(i), "value %d should not be null", i)
		assert.NotNil(t, ar.Value(i), "value %d should not be nil", i)
		assert.Equal(t, 0, len(ar.Value(i)), "value %d should be empty slice", i)
	}
	assert.Equal(t, []byte("SGVsbG8sIFdvcmxkIQ=="), ar.Value(2))

	// Case 2: All Empty - this is the failing case
	ab2 := array.NewBinaryBuilder(mem, arrow.BinaryTypes.Binary)
	defer ab2.Release()

	ab2.Append([]byte(""))
	ab2.Append([]byte(""))
	ab2.AppendEmptyValue()

	ar2 := ab2.NewBinaryArray()
	defer ar2.Release()

	assert.Equal(t, 3, ar2.Len())
	assert.Equal(t, 0, ar2.NullN(), "no values should be null")

	// All three should be empty slices, not nil
	for i := 0; i < 3; i++ {
		assert.False(t, ar2.IsNull(i), "value %d should not be null", i)
		assert.NotNil(t, ar2.Value(i), "value %d should not be nil", i)
		assert.Equal(t, 0, len(ar2.Value(i)), "value %d should be empty slice", i)
	}

	// Case 3: All Null
	ab3 := array.NewBinaryBuilder(mem, arrow.BinaryTypes.Binary)
	defer ab3.Release()

	ab3.AppendNull()
	ab3.AppendNull()
	ab3.AppendNull()

	ar3 := ab3.NewBinaryArray()
	defer ar3.Release()

	assert.Equal(t, 3, ar3.Len())
	assert.Equal(t, 3, ar3.NullN(), "all values should be null")

	for i := 0; i < 3; i++ {
		assert.True(t, ar3.IsNull(i), "value %d should be null", i)
		assert.Empty(t, ar3.Value(i), "value %d should be nil", i)
		assert.Zero(t, len(ar3.Value(i)), "value %d should be empty slice", i)
	}
}
