/*
 * 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.
 */
package org.apache.cassandra.auth;

import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Optional;

import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.utils.FBUtilities;

public class RoleOptions
{
    private final Map<IRoleManager.Option, Object> options = new HashMap<>();

    /**
     * Set a value for a specific option.
     * Throws SyntaxException if the same option is set multiple times
     * @param option
     * @param value
     */
    public void setOption(IRoleManager.Option option, Object value)
    {
        if (options.containsKey(option))
            throw new SyntaxException(String.format("Multiple definition for property '%s'", option.name()));
        options.put(option, value);
    }

    /**
     * Return true if there are no options with values set, false otherwise
     * @return whether any options have values set or not
     */
    public boolean isEmpty()
    {
        return options.isEmpty();
    }

    /**
     * Return a map of all the options which have been set
     * @return all options with values
     */
    public Map<IRoleManager.Option, Object> getOptions()
    {
        return options;
    }

    /**
     * Return a boolean value of the superuser option
     * @return superuser option value
     */
    public Optional<Boolean> getSuperuser()
    {
        return Optional.fromNullable((Boolean)options.get(IRoleManager.Option.SUPERUSER));
    }

    /**
     * Return a boolean value of the login option
     * @return login option value
     */
    public Optional<Boolean> getLogin()
    {
        return Optional.fromNullable((Boolean)options.get(IRoleManager.Option.LOGIN));
    }

    /**
     * Return the string value of the password option
     * @return password option value
     */
    public Optional<String> getPassword()
    {
        return Optional.fromNullable((String)options.get(IRoleManager.Option.PASSWORD));
    }

    /**
     * Return a {@code Map<String, String>} representing custom options
     * It is the responsiblity of IRoleManager implementations which support
     * IRoleManager.Option.OPTION to handle type checking and conversion of these
     * values, if present
     * @return map of custom options
     */
    @SuppressWarnings("unchecked")
    public Optional<Map<String, String>> getCustomOptions()
    {
        return Optional.fromNullable((Map<String, String>)options.get(IRoleManager.Option.OPTIONS));
    }

    /**
     * Validate the contents of the options in two ways:
     * - Ensure that only a subset of the options supported by the configured IRoleManager are set
     * - Validate the type of any option values present.
     * Should either condition fail, then InvalidRequestException is thrown. This method is called
     * during validation of CQL statements, so the IRE results in a error response to the client.
     *
     * @throws InvalidRequestException if any options which are not supported by the configured IRoleManager
     *     are set or if any option value is of an incorrect type.
     */
    public void validate()
    {
        for (Map.Entry<IRoleManager.Option, Object> option : options.entrySet())
        {
            if (!DatabaseDescriptor.getRoleManager().supportedOptions().contains(option.getKey()))
                throw new InvalidRequestException(String.format("%s doesn't support %s",
                                                                DatabaseDescriptor.getRoleManager().getClass().getName(),
                                                                option.getKey()));
            switch (option.getKey())
            {
                case LOGIN:
                case SUPERUSER:
                    if (!(option.getValue() instanceof Boolean))
                        throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
                                                                        "It must be a boolean",
                                                                        option.getKey()));
                    break;
                case PASSWORD:
                    if (!(option.getValue() instanceof String))
                        throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
                                                                        "It must be a string",
                                                                        option.getKey()));
                    break;
                case OPTIONS:
                    if (!(option.getValue() instanceof Map))
                        throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
                                                                        "It must be a map",
                                                                        option.getKey()));
                    break;

            }
        }
    }

    public String toString()
    {
        return FBUtilities.toString(options);
    }
}
