/*
 * 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 swift.
    /// </summary>
    public sealed class SwiftServiceConfig : IServiceConfig
    {
        /// <summary>
        /// The container for Swift.
        /// </summary>
        public string? Container { get; init; }
        /// <summary>
        /// The endpoint for Swift.
        /// </summary>
        public string? Endpoint { get; init; }
        /// <summary>
        /// The root for Swift.
        /// </summary>
        public string? Root { get; init; }
        /// <summary>
        /// The hash algorithm for TempURL signing. Supported values: `sha1`, `sha256`, `sha512`. Defaults to `sha256`. The cluster must have the chosen algorithm in its `tempurl.allowed_digests` (check `GET /info`).
        /// </summary>
        public string? TempUrlHashAlgorithm { get; init; }
        /// <summary>
        /// The TempURL key for generating presigned URLs. This corresponds to the `X-Account-Meta-Temp-URL-Key` or `X-Container-Meta-Temp-URL-Key` header value configured on the Swift account or container.
        /// </summary>
        public string? TempUrlKey { get; init; }
        /// <summary>
        /// The token for Swift.
        /// </summary>
        public string? Token { get; init; }

        public string Scheme => "swift";

        public IReadOnlyDictionary<string, string> ToOptions()
        {
            var map = new Dictionary<string, string>();
            if (Container is not null)
            {
                map["container"] = Utilities.ToOptionString(Container);
            }
            if (Endpoint is not null)
            {
                map["endpoint"] = Utilities.ToOptionString(Endpoint);
            }
            if (Root is not null)
            {
                map["root"] = Utilities.ToOptionString(Root);
            }
            if (TempUrlHashAlgorithm is not null)
            {
                map["temp_url_hash_algorithm"] = Utilities.ToOptionString(TempUrlHashAlgorithm);
            }
            if (TempUrlKey is not null)
            {
                map["temp_url_key"] = Utilities.ToOptionString(TempUrlKey);
            }
            if (Token is not null)
            {
                map["token"] = Utilities.ToOptionString(Token);
            }
            return map;
        }
    }

}
