/*
 * 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 cos.
    /// </summary>
    public sealed class CosServiceConfig : IServiceConfig
    {
        /// <summary>
        /// Bucket of this backend.
        /// </summary>
        public string? Bucket { get; init; }
        /// <summary>
        /// Disable config load so that opendal will not load config from
        /// </summary>
        public bool? DisableConfigLoad { get; init; }
        /// <summary>
        /// Deprecated: COS versioning capability is enabled by default.
        /// </summary>
        [System.Obsolete("COS versioning capability is enabled by default and this option is no longer needed.")]
        public bool? EnableVersioning { get; init; }
        /// <summary>
        /// Endpoint of this backend.
        /// </summary>
        public string? Endpoint { get; init; }
        /// <summary>
        /// Root of this backend.
        /// </summary>
        public string? Root { get; init; }
        /// <summary>
        /// Secret ID of this backend.
        /// </summary>
        public string? SecretId { get; init; }
        /// <summary>
        /// Secret key of this backend.
        /// </summary>
        public string? SecretKey { get; init; }
        /// <summary>
        /// Security token (a.k.a. session token) of this backend. This is used for temporary credentials issued by Tencent Cloud STS (e.g. `GetFederationToken` / `AssumeRole`). When `security_token` is provided, it will be used together with `secret_id` and `secret_key` to sign requests, and the `x-cos-security-token` header will be attached automatically by the signer. If this field is not set, OpenDAL will also fall back to reading the token from environment variables `TENCENTCLOUD_TOKEN`, `TENCENTCLOUD_SECURITY_TOKEN` or `QCLOUD_SECRET_TOKEN` (unless `disable_config_load` is enabled).
        /// </summary>
        public string? SecurityToken { get; init; }

        public string Scheme => "cos";

        public IReadOnlyDictionary<string, string> ToOptions()
        {
            var map = new Dictionary<string, string>();
            if (Bucket is not null)
            {
                map["bucket"] = Utilities.ToOptionString(Bucket);
            }
            if (DisableConfigLoad is not null)
            {
                map["disable_config_load"] = Utilities.ToOptionString(DisableConfigLoad);
            }
#pragma warning disable CS0618
            if (EnableVersioning is not null)
            {
                map["enable_versioning"] = Utilities.ToOptionString(EnableVersioning);
            }
#pragma warning restore CS0618
            if (Endpoint is not null)
            {
                map["endpoint"] = Utilities.ToOptionString(Endpoint);
            }
            if (Root is not null)
            {
                map["root"] = Utilities.ToOptionString(Root);
            }
            if (SecretId is not null)
            {
                map["secret_id"] = Utilities.ToOptionString(SecretId);
            }
            if (SecretKey is not null)
            {
                map["secret_key"] = Utilities.ToOptionString(SecretKey);
            }
            if (SecurityToken is not null)
            {
                map["security_token"] = Utilities.ToOptionString(SecurityToken);
            }
            return map;
        }
    }

}
