/*
 * 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.Set;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;

import org.apache.cassandra.config.DatabaseDescriptor;

/**
 * IResource implementation representing database roles.
 *
 * The root level "roles" resource represents the collection of all Roles.
 * Individual roles are represented as members of the collection:
 * "roles"                    - the root level collection resource
 * "roles/role1"              - a specific database role
 */
public class RoleResource implements IResource, Comparable<RoleResource>
{
    enum Level
    {
        ROOT, ROLE
    }

    // permissions which may be granted on the root level resource
    private static final Set<Permission> ROOT_LEVEL_PERMISSIONS = Sets.immutableEnumSet(Permission.CREATE,
                                                                                        Permission.ALTER,
                                                                                        Permission.DROP,
                                                                                        Permission.AUTHORIZE,
                                                                                        Permission.DESCRIBE);
    // permissions which may be granted on role level resources
    private static final Set<Permission> ROLE_LEVEL_PERMISSIONS = Sets.immutableEnumSet(Permission.ALTER,
                                                                                        Permission.DROP,
                                                                                        Permission.AUTHORIZE,
                                                                                        Permission.DESCRIBE);

    private static final String ROOT_NAME = "roles";
    private static final RoleResource ROOT_RESOURCE = new RoleResource();

    private final Level level;
    private final String name;

    private RoleResource()
    {
        level = Level.ROOT;
        name = null;
    }

    private RoleResource(String name)
    {
        level = Level.ROLE;
        this.name = name;
    }

    /**
     * @return the root-level resource.
     */
    public static RoleResource root()
    {
        return ROOT_RESOURCE;
    }

    /**
     * Creates a RoleResource representing an individual Role.
     * @param name name of the Role.
     * @return RoleResource instance reresenting the Role.
     */
    public static RoleResource role(String name)
    {
        return new RoleResource(name);
    }

    /**
     * Parses a role resource name into a RoleResource instance.
     *
     * @param name Name of the data resource.
     * @return RoleResource instance matching the name.
     */
    public static RoleResource fromName(String name)
    {
        String[] parts = StringUtils.split(name, "/", 2);

        if (!parts[0].equals(ROOT_NAME))
            throw new IllegalArgumentException(String.format("%s is not a valid role resource name", name));

        if (parts.length == 1)
            return root();

        return role(parts[1]);
    }

    /**
     * @return Printable name of the resource.
     */
    public String getName()
    {
        return level == Level.ROOT ? ROOT_NAME : String.format("%s/%s", ROOT_NAME, name);
    }

    /**
     * @return short form name of a role level resource. i.e. not the full "root/name" version returned by getName().
     * Throws IllegalStateException if called on the root-level resource.
     */
    public String getRoleName()
    {
        if (level == Level.ROOT)
            throw new IllegalStateException(String.format("%s role resource has no role name", level));
        return name;
    }

    /**
     * @return Parent of the resource, if any. Throws IllegalStateException if it's the root-level resource.
     */
    public IResource getParent()
    {
        if (level == Level.ROLE)
            return root();

        throw new IllegalStateException("Root-level resource can't have a parent");
    }

    public boolean hasParent()
    {
        return level != Level.ROOT;
    }

    public boolean exists()
    {
        return level == Level.ROOT || DatabaseDescriptor.getRoleManager().isExistingRole(this);
    }

    public Set<Permission> applicablePermissions()
    {
        return level == Level.ROOT ? ROOT_LEVEL_PERMISSIONS : ROLE_LEVEL_PERMISSIONS;
    }

    public int compareTo(RoleResource o)
    {
        return this.name.compareTo(o.name);
    }

    @Override
    public String toString()
    {
        return level == Level.ROOT ? "<all roles>" : String.format("<role %s>", name);
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
            return true;

        if (!(o instanceof RoleResource))
            return false;

        RoleResource rs = (RoleResource) o;

        return Objects.equal(level, rs.level) && Objects.equal(name, rs.name);
    }

    @Override
    public int hashCode()
    {
        return Objects.hashCode(level, name);
    }
}
