/*
 * 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 redis.
    /// </summary>
    public sealed class RedisServiceConfig : IServiceConfig
    {
        /// <summary>
        /// network address of the Redis cluster service. Can be "tcp://127.0.0.1:6379,tcp://127.0.0.1:6380,tcp://127.0.0.1:6381", e.g. default is None
        /// </summary>
        public string? ClusterEndpoints { get; init; }
        /// <summary>
        /// The maximum number of connections allowed. default is 10
        /// </summary>
        public long? ConnectionPoolMaxSize { get; init; }
        /// <summary>
        /// the number of DBs redis can take is unlimited default is db 0
        /// </summary>
        public long Db { get; init; }
        /// <summary>
        /// The default ttl for put operations.
        /// </summary>
        public string? DefaultTtl { get; init; }
        /// <summary>
        /// network address of the Redis service. Can be "tcp://127.0.0.1:6379", e.g. default is "tcp://127.0.0.1:6379"
        /// </summary>
        public string? Endpoint { get; init; }
        /// <summary>
        /// the password for authentication default is None
        /// </summary>
        public string? Password { get; init; }
        /// <summary>
        /// the working directory of the Redis service. Can be "/path/to/dir" default is "/"
        /// </summary>
        public string? Root { get; init; }
        /// <summary>
        /// the username to connect redis service. default is None
        /// </summary>
        public string? Username { get; init; }

        public string Scheme => "redis";

        public IReadOnlyDictionary<string, string> ToOptions()
        {
            var map = new Dictionary<string, string>();
            if (ClusterEndpoints is not null)
            {
                map["cluster_endpoints"] = Utilities.ToOptionString(ClusterEndpoints);
            }
            if (ConnectionPoolMaxSize is not null)
            {
                map["connection_pool_max_size"] = Utilities.ToOptionString(ConnectionPoolMaxSize);
            }
            map["db"] = Utilities.ToOptionString(Db);
            if (DefaultTtl is not null)
            {
                map["default_ttl"] = Utilities.ToOptionString(DefaultTtl);
            }
            if (Endpoint is not null)
            {
                map["endpoint"] = Utilities.ToOptionString(Endpoint);
            }
            if (Password is not null)
            {
                map["password"] = Utilities.ToOptionString(Password);
            }
            if (Root is not null)
            {
                map["root"] = Utilities.ToOptionString(Root);
            }
            if (Username is not null)
            {
                map["username"] = Utilities.ToOptionString(Username);
            }
            return map;
        }
    }

}
