/*
 * 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 azdls.
    /// </summary>
    public sealed class AzdlsServiceConfig : IServiceConfig
    {
        /// <summary>
        /// Account key of this backend. - required for shared_key authentication
        /// </summary>
        public string? AccountKey { get; init; }
        /// <summary>
        /// Account name of this backend.
        /// </summary>
        public string? AccountName { get; init; }
        /// <summary>
        /// authority_host The authority host of the service principal. - required for client_credentials authentication - default value: `https://login.microsoftonline.com`
        /// </summary>
        public string? AuthorityHost { get; init; }
        /// <summary>
        /// client_id The client id of the service principal. - required for client_credentials authentication
        /// </summary>
        public string? ClientId { get; init; }
        /// <summary>
        /// client_secret The client secret of the service principal. - required for client_credentials authentication
        /// </summary>
        public string? ClientSecret { get; init; }
        /// <summary>
        /// Whether hierarchical namespace (HNS) is enabled for the storage account. When enabled, recursive deletion can use pagination to avoid timeouts on large directories. - default value: `false`
        /// </summary>
        public bool? EnableHns { get; init; }
        /// <summary>
        /// Endpoint of this backend.
        /// </summary>
        public string? Endpoint { get; init; }
        /// <summary>
        /// Filesystem name of this backend.
        /// </summary>
        public string? Filesystem { get; init; }
        /// <summary>
        /// Root of this backend.
        /// </summary>
        public string? Root { get; init; }
        /// <summary>
        /// sas_token The shared access signature token. - required for sas authentication
        /// </summary>
        public string? SasToken { get; init; }
        /// <summary>
        /// tenant_id The tenant id of the service principal. - required for client_credentials authentication
        /// </summary>
        public string? TenantId { get; init; }

        public string Scheme => "azdls";

        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);
            }
            if (AuthorityHost is not null)
            {
                map["authority_host"] = Utilities.ToOptionString(AuthorityHost);
            }
            if (ClientId is not null)
            {
                map["client_id"] = Utilities.ToOptionString(ClientId);
            }
            if (ClientSecret is not null)
            {
                map["client_secret"] = Utilities.ToOptionString(ClientSecret);
            }
            if (EnableHns is not null)
            {
                map["enable_hns"] = Utilities.ToOptionString(EnableHns);
            }
            if (Endpoint is not null)
            {
                map["endpoint"] = Utilities.ToOptionString(Endpoint);
            }
            if (Filesystem is not null)
            {
                map["filesystem"] = Utilities.ToOptionString(Filesystem);
            }
            if (Root is not null)
            {
                map["root"] = Utilities.ToOptionString(Root);
            }
            if (SasToken is not null)
            {
                map["sas_token"] = Utilities.ToOptionString(SasToken);
            }
            if (TenantId is not null)
            {
                map["tenant_id"] = Utilities.ToOptionString(TenantId);
            }
            return map;
        }
    }

}
