// 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.

using System.Buffers;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using Apache.Arrow.Operations.VariantJson;
using Apache.Arrow.Scalars.Variant;
using BenchmarkDotNet.Attributes;

namespace Apache.Arrow.Variant.Benchmarks
{
    /// <summary>
    /// Measures encoding (VariantValue → binary, JSON → binary),
    /// decoding (binary → VariantValue), and round-trip performance.
    /// <see cref="MemoryDiagnoserAttribute"/> reports allocations per operation
    /// to quantify MemoryStream / intermediate object overhead.
    /// </summary>
    [MemoryDiagnoser]
    public class EncodingBenchmarks
    {
        // Pre-built test data, set up once before benchmarks run.
        private VariantValue _flatObject;
        private VariantValue _nestedObject;
        private VariantValue _largeArray;

        private byte[] _flatJson;
        private byte[] _nestedJson;
        private byte[] _arrayJson;

        private byte[] _flatMetadata;
        private byte[] _flatValue;
        private byte[] _nestedMetadata;
        private byte[] _nestedValue;
        private byte[] _arrayMetadata;
        private byte[] _arrayValue;

        [GlobalSetup]
        public void Setup()
        {
            // --- Flat object: 20 primitive fields ---
            Dictionary<string, VariantValue> flatFields = new Dictionary<string, VariantValue>();
            for (int i = 0; i < 20; i++)
            {
                flatFields["field_" + i] = i % 3 == 0
                    ? VariantValue.FromInt32(i * 100)
                    : i % 3 == 1
                        ? VariantValue.FromDouble(i * 1.5)
                        : VariantValue.FromString("value_" + i);
            }
            _flatObject = VariantValue.FromObject(flatFields);

            // --- Nested object: 5 levels deep, 4 fields per level ---
            _nestedObject = BuildNestedObject(5, 4);

            // --- Large array: 100 mixed elements ---
            List<VariantValue> elements = new List<VariantValue>();
            for (int i = 0; i < 100; i++)
            {
                elements.Add(i % 2 == 0
                    ? VariantValue.FromInt32(i)
                    : VariantValue.FromString("item_" + i));
            }
            _largeArray = VariantValue.FromArray(elements);

            // --- JSON versions ---
            _flatJson = Encoding.UTF8.GetBytes(VariantJsonWriter.ToJson(_flatObject));
            _nestedJson = Encoding.UTF8.GetBytes(VariantJsonWriter.ToJson(_nestedObject));
            _arrayJson = Encoding.UTF8.GetBytes(VariantJsonWriter.ToJson(_largeArray));

            // --- Binary versions (for decode benchmarks) ---
            VariantBuilder builder = new VariantBuilder();
            (_flatMetadata, _flatValue) = builder.Encode(_flatObject);
            (_nestedMetadata, _nestedValue) = builder.Encode(_nestedObject);
            (_arrayMetadata, _arrayValue) = builder.Encode(_largeArray);
        }

        private static VariantValue BuildNestedObject(int depth, int fieldsPerLevel)
        {
            if (depth == 0)
            {
                return VariantValue.FromString("leaf");
            }

            Dictionary<string, VariantValue> fields = new Dictionary<string, VariantValue>();
            for (int i = 0; i < fieldsPerLevel; i++)
            {
                fields["key_" + i] = i == 0
                    ? BuildNestedObject(depth - 1, fieldsPerLevel)
                    : VariantValue.FromInt32(i * depth);
            }
            return VariantValue.FromObject(fields);
        }

        // ---------------------------------------------------------------
        // Encode: VariantValue → binary
        // ---------------------------------------------------------------

        [Benchmark]
        public byte[] Encode_FlatObject()
        {
            VariantBuilder builder = new VariantBuilder();
            return builder.Encode(_flatObject).Value;
        }

        [Benchmark]
        public byte[] Encode_NestedObject()
        {
            VariantBuilder builder = new VariantBuilder();
            return builder.Encode(_nestedObject).Value;
        }

        [Benchmark]
        public byte[] Encode_LargeArray()
        {
            VariantBuilder builder = new VariantBuilder();
            return builder.Encode(_largeArray).Value;
        }

        // ---------------------------------------------------------------
        // VariantJsonReader: UTF-8 JSON → binary (streaming, no VariantValue)
        // ---------------------------------------------------------------

        [Benchmark]
        public byte[] EncodeFromJson_FlatObject()
        {
            return VariantJsonReader.Parse(_flatJson).Value;
        }

        [Benchmark]
        public byte[] EncodeFromJson_NestedObject()
        {
            return VariantJsonReader.Parse(_nestedJson).Value;
        }

        [Benchmark]
        public byte[] EncodeFromJson_LargeArray()
        {
            return VariantJsonReader.Parse(_arrayJson).Value;
        }

        // ---------------------------------------------------------------
        // Decode: binary → VariantValue
        // ---------------------------------------------------------------

        [Benchmark]
        public VariantValue Decode_FlatObject()
        {
            VariantReader reader = new VariantReader(_flatMetadata, _flatValue);
            return reader.ToVariantValue();
        }

        [Benchmark]
        public VariantValue Decode_NestedObject()
        {
            VariantReader reader = new VariantReader(_nestedMetadata, _nestedValue);
            return reader.ToVariantValue();
        }

        [Benchmark]
        public VariantValue Decode_LargeArray()
        {
            VariantReader reader = new VariantReader(_arrayMetadata, _arrayValue);
            return reader.ToVariantValue();
        }

        // ---------------------------------------------------------------
        // JSON write: binary → JSON string (ToJson: MemoryStream + StreamReader)
        // ---------------------------------------------------------------

        [Benchmark]
        public string WriteJson_FlatObject()
        {
            return VariantJsonWriter.ToJson(_flatMetadata, _flatValue);
        }

        [Benchmark]
        public string WriteJson_NestedObject()
        {
            return VariantJsonWriter.ToJson(_nestedMetadata, _nestedValue);
        }

        // ---------------------------------------------------------------
        // JSON write: binary → Utf8JsonWriter (WriteTo: no string materialization)
        // ---------------------------------------------------------------

        [Benchmark]
        public void WriteTo_FlatObject()
        {
            ArrayBufferWriter<byte> buffer = new ArrayBufferWriter<byte>();
            using (Utf8JsonWriter writer = new Utf8JsonWriter(buffer))
            {
                VariantJsonWriter.WriteTo(writer, _flatMetadata, _flatValue);
            }
        }

        [Benchmark]
        public void WriteTo_NestedObject()
        {
            ArrayBufferWriter<byte> buffer = new ArrayBufferWriter<byte>();
            using (Utf8JsonWriter writer = new Utf8JsonWriter(buffer))
            {
                VariantJsonWriter.WriteTo(writer, _nestedMetadata, _nestedValue);
            }
        }

        // ---------------------------------------------------------------
        // Round-trip: JSON → binary → JSON
        // ---------------------------------------------------------------

        [Benchmark]
        public string RoundTrip_FlatObject()
        {
            (byte[] metadata, byte[] value) = VariantJsonReader.Parse(_flatJson);
            return VariantJsonWriter.ToJson(metadata, value);
        }

        [Benchmark]
        public string RoundTrip_NestedObject()
        {
            (byte[] metadata, byte[] value) = VariantJsonReader.Parse(_nestedJson);
            return VariantJsonWriter.ToJson(metadata, value);
        }
    }
}
