/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*
*  Licensed to Elasticsearch B.V. under one or more contributor
*  license agreements. See the NOTICE file distributed with
*  this work for additional information regarding copyright
*  ownership. Elasticsearch B.V. 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;
using System.Collections.Generic;
using OpenSearch.Net.Utf8Json;
namespace OpenSearch.Client.Specification.IndicesApi
{
	/// 
	/// Dynamic index settings
	/// 
	[InterfaceDataContract]
	[JsonFormatter(typeof(DynamicIndexSettingsFormatter))]
	public interface IDynamicIndexSettings : IIsADictionary
	{
		/// 
		/// Configure analysis
		/// 
		IAnalysis Analysis { get; set; }
		/// 
		/// Auto-expand the number of replicas based on the number of available nodes.
		///  Set to a dash delimited lower and upper bound (e.g. 0-5) or use all for the upper bound (e.g. 0-all). Defaults to false (i.e. disabled).
		/// 
		AutoExpandReplicas AutoExpandReplicas { get; set; }
		/// 
		/// Set to true to disable index metadata reads and writes.
		/// 
		bool? BlocksMetadata { get; set; }
		/// 
		/// Set to true to disable read operations against the index.
		/// 
		bool? BlocksRead { get; set; }
		/// 
		/// Set to true to make the index and index metadata read only, false to allow writes and metadata changes.
		/// 
		bool? BlocksReadOnly { get; set; }
		/// 
		/// Set to true to disable write operations against the index.
		/// 
		bool? BlocksWrite { get; set; }
		/// 
		/// Set to true to disable read operations, but allow delete operations, against the index.
		/// 
		bool? BlocksReadOnlyAllowDelete { get; set; }
		/// 
		/// All of the settings exposed in the merge module are expert only and may be obsoleted in the future at any time!
		/// 
		IMergeSettings Merge { get; set; }
		/// 
		/// The number of replicas each primary shard has. Defaults to 1.
		/// 
		int? NumberOfReplicas { get; set; }
		/// 
		/// Unallocated shards are recovered in order of priority when set
		/// 
		int? Priority { get; set; }
		/// 
		/// A primary shard is only recovered only if there are
		/// enough nodes available to allocate sufficient replicas to form a quorum.
		/// 
		Union RecoveryInitialShards { get; set; }
		/// 
		/// How often to perform a refresh operation, which makes recent changes to the index visible to search.
		/// Defaults to 1s. Can be set to -1 to disable refresh.
		/// 
		Time RefreshInterval { get; set; }
		/// 
		/// Enables the shard-level request cache. Not enabled by default.
		/// 
		bool? RequestsCacheEnabled { get; set; }
		/// 
		/// The maximum number of shards (replicas and primaries) that will be allocated to a single node. Defaults to unbounded.
		/// 
		int? RoutingAllocationTotalShardsPerNode { get; set; }
		/// 
		/// Configure similarity
		/// 
		ISimilarities Similarity { get; set; }
		/// 
		/// Configure logging thresholds and levels in OpenSearch for search/fetch and indexing
		/// 
		ISlowLog SlowLog { get; set; }
		/// 
		/// Configure translog settings. This should only be used by experts who know what they're doing
		/// 
		ITranslogSettings Translog { get; set; }
		/// 
		/// The allocation of replica shards which become unassigned because a node has left can be
		/// delayed with this dynamic setting, which defaults to 1m.
		/// 
		Time UnassignedNodeLeftDelayedTimeout { get; set; }
		/// 
		/// The default ingest node pipeline for this index. Index requests will fail if the default pipeline is set and
		/// the pipeline does not exist. The default may be overridden using the pipeline parameter.
		/// The special pipeline name _none indicates no ingest pipeline should be run.`
		/// 
		string DefaultPipeline { get; set; }
		/// 
		/// The final ingest pipeline for this index. Index requests will fail if the final pipeline is set and the pipeline does not exist.
		/// The final pipeline always runs after the request pipeline (if specified) and the default pipeline (if it exists). The special pipeline
		/// name `_none` indicates no ingest pipeline will run.
		/// 
		string FinalPipeline { get; set; }
	}
	/// 
	public class DynamicIndexSettings : IsADictionaryBase, IDynamicIndexSettings
	{
		private Time _refreshInterval;
		public DynamicIndexSettings() { }
		public DynamicIndexSettings(IDictionary container) : base(container) { }
		/// 
		public IAnalysis Analysis { get; set; }
		/// 
		public AutoExpandReplicas AutoExpandReplicas { get; set; }
		/// 
		public bool? BlocksMetadata { get; set; }
		/// 
		public bool? BlocksRead { get; set; }
		/// 
		public bool? BlocksReadOnly { get; set; }
		/// 
		public bool? BlocksWrite { get; set; }
		/// 
		public bool? BlocksReadOnlyAllowDelete { get; set; }
		/// 
		public IMergeSettings Merge { get; set; }
		/// 
		public int? NumberOfReplicas { get; set; }
		/// 
		public int? Priority { get; set; }
		/// 
		public Union RecoveryInitialShards { get; set; }
		/// 
		public Time RefreshInterval
		{
			get => _refreshInterval;
			set
			{
				BackingDictionary[UpdatableIndexSettings.RefreshInterval] = value;
				_refreshInterval = value;
			}
		}
		/// 
		public bool? RequestsCacheEnabled { get; set; }
		/// 
		public int? RoutingAllocationTotalShardsPerNode { get; set; }
		/// 
		public ISimilarities Similarity { get; set; }
		/// 
		public ISlowLog SlowLog { get; set; }
		/// 
		public ITranslogSettings Translog { get; set; }
		/// 
		public Time UnassignedNodeLeftDelayedTimeout { get; set; }
		/// 
		public string DefaultPipeline { get; set; }
		/// 
		public string FinalPipeline { get; set; }
		///  Add any setting to the index 
		public void Add(string setting, object value) => BackingDictionary[setting] = value;
	}
	/// 
	public class DynamicIndexSettingsDescriptor : DynamicIndexSettingsDescriptorBase
	{
		public DynamicIndexSettingsDescriptor() : base(new DynamicIndexSettings()) { }
	}
	/// Base descriptor implementation for dynamic index settings
	public abstract class DynamicIndexSettingsDescriptorBase
		: IsADictionaryDescriptorBase
		where TDescriptor : DynamicIndexSettingsDescriptorBase
		where TIndexSettings : class, IDynamicIndexSettings
	{
		protected DynamicIndexSettingsDescriptorBase(TIndexSettings instance) : base(instance) { }
		/// 
		public TDescriptor Setting(string setting, object value)
		{
			PromisedValue[setting] = value;
			return (TDescriptor)this;
		}
		/// 
		public TDescriptor NumberOfReplicas(int? numberOfReplicas) => Assign(numberOfReplicas, (a, v) => a.NumberOfReplicas = v);
		/// 
		public TDescriptor AutoExpandReplicas(AutoExpandReplicas autoExpandReplicas) => Assign(autoExpandReplicas, (a, v) => a.AutoExpandReplicas = v);
		/// 
		public TDescriptor DefaultPipeline(string defaultPipeline) => Assign(defaultPipeline, (a, v) => a.DefaultPipeline = v);
		/// 
		public TDescriptor FinalPipeline(string finalPipeline) => Assign(finalPipeline, (a, v) => a.FinalPipeline = v);
		/// 
		public TDescriptor BlocksMetadata(bool? blocksMetadata = true) => Assign(blocksMetadata, (a, v) => a.BlocksMetadata = v);
		/// 
		public TDescriptor BlocksRead(bool? blocksRead = true) => Assign(blocksRead, (a, v) => a.BlocksRead = v);
		/// 
		public TDescriptor BlocksReadOnly(bool? blocksReadOnly = true) => Assign(blocksReadOnly, (a, v) => a.BlocksReadOnly = v);
		/// 
		public TDescriptor BlocksWrite(bool? blocksWrite = true) => Assign(blocksWrite, (a, v) => a.BlocksWrite = v);
		/// 
		public TDescriptor BlocksReadOnlyAllowDelete(bool? blocksReadOnlyAllowDelete = true) => Assign(blocksReadOnlyAllowDelete, (a, v) => a.BlocksReadOnlyAllowDelete = v);
		/// 
		public TDescriptor Priority(int? priority) => Assign(priority, (a, v) => a.Priority = v);
		/// 
		public TDescriptor Merge(Func merge) =>
			Assign(merge, (a, v) => a.Merge = v?.Invoke(new MergeSettingsDescriptor()));
		/// 
		public TDescriptor RecoveryInitialShards(Union initialShards) =>
			Assign(initialShards, (a, v) => a.RecoveryInitialShards = v);
		/// 
		public TDescriptor RequestsCacheEnabled(bool? enable = true) =>
			Assign(enable, (a, v) => a.RequestsCacheEnabled = v);
		/// 
		public TDescriptor RefreshInterval(Time time) => Assign(time, (a, v) => a.RefreshInterval = v);
		/// 
		public TDescriptor RoutingAllocationTotalShardsPerNode(int? totalShardsPerNode) =>
			Assign(totalShardsPerNode, (a, v) => a.RoutingAllocationTotalShardsPerNode = v);
		/// 
		public TDescriptor SlowLog(Func slowLogSelector) =>
			Assign(slowLogSelector, (a, v) => a.SlowLog = v?.Invoke(new SlowLogDescriptor()));
		/// 
		public TDescriptor Translog(Func translogSelector) =>
			Assign(translogSelector, (a, v) => a.Translog = v?.Invoke(new TranslogSettingsDescriptor()));
		/// 
		public TDescriptor UnassignedNodeLeftDelayedTimeout(Time time) =>
			Assign(time, (a, v) => a.UnassignedNodeLeftDelayedTimeout = v);
		/// 
		public TDescriptor Analysis(Func selector) =>
			Assign(selector, (a, v) => a.Analysis = v?.Invoke(new AnalysisDescriptor()));
		/// 
		public TDescriptor Similarity(Func> selector) =>
			Assign(selector, (a, v) => a.Similarity = v?.Invoke(new SimilaritiesDescriptor())?.Value);
	}
}