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

#pragma once

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>

#include "paimon/memory/memory_pool.h"
#include "paimon/predicate/literal.h"
#include "paimon/result.h"
#include "paimon/visibility.h"

struct ArrowArray;
struct ArrowSchema;

namespace paimon {

/// Arguments controlling how a variant value is cast to a target type in `Variant::VariantGet`.
struct PAIMON_EXPORT VariantCastArgs {
    /// Whether an invalid cast fails the call (true) or yields SQL NULL (false).
    bool fail_on_error = true;
    /// The time zone used when rendering TIMESTAMP values. Supported forms are `UTC`/`Z`/`GMT`,
    /// fixed offsets such as `+08:00`, and IANA region ids such as `Asia/Shanghai`.
    std::string zone_id = "UTC";
};

/// A Variant represents a type that contains one of: 1) Primitive: A type and corresponding
/// value (e.g. INT, STRING); 2) Array: An ordered list of Variant values; 3) Object: An
/// unordered collection of string/Variant pairs (i.e. key/value pairs). An object may not
/// contain duplicate keys.
///
/// A Variant is encoded with 2 binaries: the value and the metadata, following the parquet
/// Variant Binary Encoding specification (compatible with the Java / Spark implementation). The
/// encoding allows representation of semi-structured data (e.g. JSON) in a form that can be
/// efficiently queried by path.
///
/// In an Arrow schema, a Variant field is represented as
/// `struct<value: binary not null, metadata: binary not null>` marked with Paimon-specific field
/// metadata; use `Variant::ArrowField` to construct such a field.
class PAIMON_EXPORT Variant {
 public:
    ~Variant();

    /// Parses a JSON string as a Variant (duplicate object keys are rejected).
    ///
    /// @param json The JSON document text.
    /// @param pool The memory pool used for the variant buffers.
    /// @return A result containing the created variant or an error.
    static Result<std::unique_ptr<Variant>> FromJson(const std::string& json,
                                                     const std::shared_ptr<MemoryPool>& pool);

    /// Creates a Variant from already-encoded value and metadata binaries (copied into `pool`).
    ///
    /// @param value The variant value binary.
    /// @param value_length The length of the value binary.
    /// @param metadata The variant metadata binary.
    /// @param metadata_length The length of the metadata binary.
    /// @param pool The memory pool used for the variant buffers.
    /// @return A result containing the created variant or an error.
    static Result<std::unique_ptr<Variant>> Create(const char* value, uint64_t value_length,
                                                   const char* metadata, uint64_t metadata_length,
                                                   const std::shared_ptr<MemoryPool>& pool);

    /// The variant value binary. The view remains valid as long as this variant exists.
    std::string_view Value() const;

    /// The variant metadata binary. The view remains valid as long as this variant exists.
    std::string_view Metadata() const;

    /// The size of the variant in bytes (value size + metadata size).
    int64_t SizeInBytes() const;

    /// Stringifies the variant in JSON format.
    ///
    /// @param zone_id The time zone used when rendering TIMESTAMP values.
    /// @return A result containing the JSON text or an error.
    Result<std::string> ToJson(const std::string& zone_id = "UTC") const;

    /// Extracts a sub-variant value according to a path which starts with a `$`, e.g. `$.key`,
    /// `$['key']`, `$["key"]`, `$.array[0]`, and casts the value to the target type.
    ///
    /// @param path The extraction path.
    /// @param target_type The target Arrow type (C data interface, consumed by the call); only
    ///        scalar types are supported. Use `VariantGetArrow` for nested targets.
    /// @param cast_args Cast behavior arguments.
    /// @return A result containing the extracted literal, or nullopt for SQL NULL (unmatched
    ///         path, variant null, or an invalid cast with `fail_on_error == false`).
    Result<std::optional<Literal>> VariantGet(const std::string& path,
                                              struct ArrowSchema* target_type,
                                              const VariantCastArgs& cast_args) const;

    /// Extracts a sub-variant value according to a path which starts with a `$` and casts the
    /// value to the (possibly nested) target field type.
    ///
    /// In addition to scalar types, the target may be a STRUCT (cast from a variant object,
    /// children matched by field name; unmatched children are null), a MAP with string keys
    /// (cast from a variant object), a LIST (cast from a variant array), or a variant-marked
    /// field created by `Variant::ArrowField` (the sub-variant is deeply re-encoded).
    ///
    /// @param path The extraction path.
    /// @param target_field The target Arrow field (C data interface, consumed by the call).
    /// @param cast_args Cast behavior arguments.
    /// @return A result containing a length-1 Arrow array of the target type whose single slot
    ///         holds the result; a null slot represents SQL NULL (unmatched path, variant null,
    ///         or an invalid cast with `fail_on_error == false`).
    Result<std::unique_ptr<struct ArrowArray>> VariantGetArrow(
        const std::string& path, struct ArrowSchema* target_field,
        const VariantCastArgs& cast_args) const;

    /// Extracts a sub-variant value according to a path which starts with a `$` and renders it
    /// as JSON text.
    ///
    /// @param path The extraction path.
    /// @param zone_id The time zone used when rendering TIMESTAMP values.
    /// @return A result containing the JSON text, or nullopt if the path does not match.
    Result<std::optional<std::string>> VariantGetJson(const std::string& path,
                                                      const std::string& zone_id = "UTC") const;

    /// Creates an Arrow field definition for the Variant type.
    ///
    /// This function constructs an Arrow Field (internally
    /// `struct<value: binary not null, metadata: binary not null>`) and exports it to the C data
    /// interface structure `::ArrowSchema`. It automatically injects Paimon-specific metadata to
    /// identify the field as a VARIANT.
    ///
    /// @param field_name The name of the Arrow field.
    /// @param nullable Whether the field is nullable.
    /// @param metadata A map of key-value metadata to be attached to the field.
    /// @return A result containing a unique pointer to the generated `::ArrowSchema` or an error.
    static Result<std::unique_ptr<struct ArrowSchema>> ArrowField(
        const std::string& field_name, bool nullable = true,
        std::unordered_map<std::string, std::string> metadata = {});

 private:
    class Impl;

    explicit Variant(std::unique_ptr<Impl>&& impl);

    std::unique_ptr<Impl> impl_;
};

/// Builds a variant-access projection field: a struct field that replaces a VARIANT column in
/// the read schema so that, instead of the full variant, only the described paths are extracted
/// at read time (reading only the required shredded sub-columns from shredded files).
///
/// Example: read `$.age` as INT64 and `$.city` as STRING from variant column `v`:
///
///     VariantAccessBuilder builder;
///     builder.AddField(age_type, "$.age");
///     builder.AddField(city_type, "$.city");
///     auto field = builder.Build("v");  // use in ReadContextBuilder::SetReadSchema
///
/// The resulting struct has one child per added field, named by its position ("0", "1", ...).
class PAIMON_EXPORT VariantAccessBuilder {
 public:
    VariantAccessBuilder();
    ~VariantAccessBuilder();

    /// Adds an extracted field.
    ///
    /// @param target_type The Arrow type the extracted value is cast to (C data interface,
    ///        consumed by the call). Nested targets follow `Variant::VariantGetArrow` semantics.
    /// @param path The extraction path, e.g. `$.a.b` or `$.array[0]`.
    /// @param fail_on_error Whether an invalid cast fails the read (true) or yields SQL NULL.
    /// @param zone_id The time zone used when rendering TIMESTAMP values.
    Status AddField(struct ArrowSchema* target_type, const std::string& path,
                    bool fail_on_error = true, const std::string& zone_id = "UTC");

    /// Builds the projection field named `field_name`, to be used in the read schema in place
    /// of the variant column with the same name.
    Result<std::unique_ptr<struct ArrowSchema>> Build(const std::string& field_name) const;

 private:
    class Impl;

    std::unique_ptr<Impl> impl_;
};

}  // namespace paimon
