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

// DO NOT EDIT IT MANUALLY. This file is generated by opendal/dev/src/generate/dotnet.rs.

using OpenDAL.ServiceConfig.Abstractions;

namespace OpenDAL.ServiceConfig
{
    /// <summary>
    /// Configuration for service azblob.
    /// </summary>
    public sealed class AzblobServiceConfig : IServiceConfig
    {
        /// <summary>
        /// The account key of Azblob service backend.
        /// </summary>
        public string? AccountKey { get; init; }
        /// <summary>
        /// The account name of Azblob service backend.
        /// </summary>
        public string? AccountName { get; init; }
        /// <summary>
        /// Deprecated: Azblob delete batch capability is enabled by default with Azure Blob's 256-operation batch limit.
        /// </summary>
        [System.Obsolete("Azblob delete batch capability is enabled by default with Azure Blob's 256-operation batch limit. Use CapabilityOverrideLayer to override delete_max_size for specific endpoints.")]
        public long? BatchMaxOperations { get; init; }
        /// <summary>
        /// The container name of Azblob service backend.
        /// </summary>
        public string? Container { get; init; }
        /// <summary>
        /// The encryption algorithm of Azblob service backend.
        /// </summary>
        public string? EncryptionAlgorithm { get; init; }
        /// <summary>
        /// The encryption key of Azblob service backend.
        /// </summary>
        public string? EncryptionKey { get; init; }
        /// <summary>
        /// The encryption key sha256 of Azblob service backend.
        /// </summary>
        public string? EncryptionKeySha256 { get; init; }
        /// <summary>
        /// The endpoint of Azblob service backend. Endpoint must be full uri, e.g. - Azblob: `https://accountname.blob.core.windows.net` - Azurite: `http://127.0.0.1:10000/devstoreaccount1`
        /// </summary>
        public string? Endpoint { get; init; }
        /// <summary>
        /// The root of Azblob service backend. All operations will happen under this root.
        /// </summary>
        public string? Root { get; init; }
        /// <summary>
        /// The sas token of Azblob service backend.
        /// </summary>
        public string? SasToken { get; init; }
        /// <summary>
        /// Skip signature will skip loading credentials and signing requests.
        /// </summary>
        public bool? SkipSignature { get; init; }

        public string Scheme => "azblob";

        public IReadOnlyDictionary<string, string> ToOptions()
        {
            var map = new Dictionary<string, string>();
            if (AccountKey is not null)
            {
                map["account_key"] = Utilities.ToOptionString(AccountKey);
            }
            if (AccountName is not null)
            {
                map["account_name"] = Utilities.ToOptionString(AccountName);
            }
#pragma warning disable CS0618
            if (BatchMaxOperations is not null)
            {
                map["batch_max_operations"] = Utilities.ToOptionString(BatchMaxOperations);
            }
#pragma warning restore CS0618
            if (Container is not null)
            {
                map["container"] = Utilities.ToOptionString(Container);
            }
            if (EncryptionAlgorithm is not null)
            {
                map["encryption_algorithm"] = Utilities.ToOptionString(EncryptionAlgorithm);
            }
            if (EncryptionKey is not null)
            {
                map["encryption_key"] = Utilities.ToOptionString(EncryptionKey);
            }
            if (EncryptionKeySha256 is not null)
            {
                map["encryption_key_sha256"] = Utilities.ToOptionString(EncryptionKeySha256);
            }
            if (Endpoint is not null)
            {
                map["endpoint"] = Utilities.ToOptionString(Endpoint);
            }
            if (Root is not null)
            {
                map["root"] = Utilities.ToOptionString(Root);
            }
            if (SasToken is not null)
            {
                map["sas_token"] = Utilities.ToOptionString(SasToken);
            }
            if (SkipSignature is not null)
            {
                map["skip_signature"] = Utilities.ToOptionString(SkipSignature);
            }
            return map;
        }
    }

}
