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

syntax = "proto3";

package datafusion_java;

import "cache_manager_options.proto";
import "object_store_options.proto";

option java_package = "org.apache.datafusion.protobuf";
option java_multiple_files = true;

// Options used to construct a SessionContext. All fields are optional —
// unset fields leave DataFusion's default behavior in place.
//
// `options` is a free-form escape hatch matching DataFusion's
// `ConfigOptions::set(key, value)` API: any `datafusion.*` config key
// can be set as a string. Entries are applied AFTER the typed fields
// above (so an explicit `options` entry overrides a typed setter for
// the same knob) and IN INSERTION ORDER (so for keys whose setters
// have side effects on other keys -- e.g.
// `datafusion.optimizer.enable_dynamic_filter_pushdown` rewrites the
// specific `enable_*_dynamic_filter_pushdown` flags -- the caller's
// last write wins deterministically).
//
// `repeated ConfigOption` is used instead of `map<string,string>`
// because protobuf maps decode into `HashMap` on the Rust side, whose
// iteration order is randomized and would otherwise break the
// last-write-wins contract for overlapping keys.
//
// Unknown keys or unparseable values surface as a RuntimeException at
// SessionContext construction.
message SessionOptions {
  optional uint64 batch_size = 1;
  optional uint64 target_partitions = 2;
  optional bool collect_statistics = 3;
  optional bool information_schema = 4;
  optional MemoryLimit memory_limit = 5;
  optional string temp_directory = 6;
  repeated ConfigOption options = 7;
  // Object store registrations to apply to the new context's RuntimeEnv.
  // Applied in order; if two registrations resolve to the same URL, the
  // later one wins (matching upstream's `RuntimeEnv::register_object_store`
  // semantics).
  repeated ObjectStoreRegistration object_stores = 8;
  // Configuration for DataFusion's built-in CacheManager. Unset = leave
  // the upstream default in place (matches existing callers).
  optional CacheManagerOptionsProto cache_manager = 9;
  // Disk-manager configuration (disable spill, size cap). Unset fields
  // leave the upstream `RuntimeEnvBuilder` default in place.
  optional DiskManagerOptions disk_manager = 10;
  // Register Apache Spark-compatible functions and expression planners on the
  // new context (via the datafusion-spark crate). Requires the native library
  // to be built with the `spark` Cargo feature (on in the default build);
  // otherwise construction fails with a clear error. Spark functions override
  // DataFusion built-ins of the same name.
  optional bool spark_functions = 11;
}

// Disk-manager configuration. The two fields are independent on the wire;
// mutual-exclusion of `disabled` against the legacy
// `SessionOptions.temp_directory` field (slot 6) is enforced at the Java
// builder level.
message DiskManagerOptions {
  // Disable spill entirely (`DiskManagerMode::Disabled`).
  optional bool disabled = 1;
  // Cap on bytes used by spill files. Mirrors upstream
  // `RuntimeEnvBuilder::with_max_temp_directory_size` 1:1. Zero is a
  // legal value upstream (means "no spill allowed"); the Java setter
  // mirrors that contract.
  optional uint64 max_temp_directory_size = 2;
}

message ConfigOption {
  string key = 1;
  string value = 2;
}

message MemoryLimit {
  uint64 max_memory_bytes = 1;
  double memory_fraction = 2;
}
