/*
 * 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.commons.vfs2.util;

import java.util.EnumMap;
import java.util.Map;

/**
 * UNIX permissions.
 *
 * @since 2.1
 */
public class PosixPermissions {

    /**
     * Permission types.
     */
    public enum Type {
        /**
         * User right readable.
         */
        UserReadable(00400),

        /**
         * User right writable.
         */
        UserWritable(00200),

        /**
         * User right executable.
         */
        UserExecutable(00100),

        /**
         * Group right readable.
         */
        GroupReadable(00040),

        /**
         * Group right writable.
         */
        GroupWritable(00020),

        /**
         * Group right executable.
         */
        GroupExecutable(00010),

        /**
         * Other right readable.
         */
        OtherReadable(00004),

        /**
         * Other right writable.
         */
        OtherWritable(00002),

        /**
         * Other right executable.
         */
        OtherExecutable(00001);

        private final int mask;

        /**
         * Initialize with the mask
         */
        Type(final int mask) {
            this.mask = mask;
        }

        /**
         * Return the mask for this permission.
         *
         * @return the mask for this permission.
         */
        public int getMask() {
            return this.mask;
        }

    }

    /**
     * Current permissions.
     */
    private final int permissions;

    /**
     * If the user is the owner of the file.
     */
    private final boolean isOwner;

    /**
     * If one user group is the group of the file.
     */
    private final boolean isInGroup;

    /**
     * Creates a new PosixPermissions object.
     *
     * @param permissions The permissions
     * @param isOwner true if the user is the owner of the file
     * @param isInGroup true if the user is a group owner of the file
     */
    public PosixPermissions(final int permissions, final boolean isOwner, final boolean isInGroup) {
        this.permissions = permissions;
        this.isOwner = isOwner;
        this.isInGroup = isInGroup;
    }

    /**
     * Computes new permission from old ones.
     *
     * @param values The permissions to set.
     * @return The new permissions.
     */
    private int computeNewPermissions(final Map<Type, Boolean> values) {
        int newPerms = this.permissions;
        for (final Map.Entry<Type, Boolean> entry : values.entrySet()) {
            final Type type = entry.getKey();
            if (entry.getValue()) {
                newPerms |= type.getMask();
            } else {
                newPerms &= ~type.getMask();
            }
        }
        return newPerms;
    }

    /**
     * Tests whether the bit corresponding to the permission is set.
     *
     * @return whether the bit corresponding to the permission is set.
     */
    private boolean get(final Type type) {
        return (type.getMask() & this.permissions) != 0;
    }

    /**
     * Gets permissions.
     *
     * @return permissions.
     */
    public int getPermissions() {
        return this.permissions;
    }

    /**
     * Gets whether the permissions are executable.
     *
     * @return whether the permissions are executable.
     */
    public boolean isExecutable() {
        if (this.isOwner) {
            return this.get(Type.UserExecutable);
        }
        if (this.isInGroup) {
            return this.get(Type.GroupExecutable);
        }
        return this.get(Type.OtherExecutable);
    }

    /**
     * Gets whether the permissions are readable.
     *
     * @return whether the permissions are readable.
     */
    public boolean isReadable() {
        if (this.isOwner) {
            return this.get(Type.UserReadable);
        }
        if (this.isInGroup) {
            return this.get(Type.GroupReadable);
        }
        return this.get(Type.OtherReadable);
    }

    /**
     * Gets whether the permissions are writable.
     *
     * @return whether the permissions are writable.
     */
    public boolean isWritable() {
        if (this.isOwner) {
            return this.get(Type.UserWritable);
        }
        if (this.isInGroup) {
            return this.get(Type.GroupWritable);
        }
        return this.get(Type.OtherWritable);
    }

    /**
     * Creates new permissions based on these permissions.
     *
     * @param executable Whether the new permissions should be readable.
     * @param ownerOnly Whether the new permissions are only for the owner.
     * @return the new permissions.
     */
    public int makeExecutable(final boolean executable, final boolean ownerOnly) {
        final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
        map.put(Type.UserExecutable, executable);
        if (!ownerOnly) {
            map.put(Type.GroupExecutable, executable);
            map.put(Type.OtherExecutable, executable);
        }
        return this.computeNewPermissions(map);
    }

    /**
     * Creates new permissions based on these permissions.
     *
     * @param readable Whether the new permissions should be readable.
     * @param ownerOnly Whether the new permissions are only for the owner.
     * @return the new permissions.
     */
    public Integer makeReadable(final boolean readable, final boolean ownerOnly) {
        final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
        map.put(Type.UserReadable, readable);
        if (!ownerOnly) {
            map.put(Type.GroupReadable, readable);
            map.put(Type.OtherReadable, readable);
        }
        return this.computeNewPermissions(map);
    }

    /**
     * Creates new permissions based on these permissions.
     *
     * @param writable Whether the new permissions should be readable.
     * @param ownerOnly Whether the new permissions are only for the owner.
     * @return the new permissions.
     */
    public Integer makeWritable(final boolean writable, final boolean ownerOnly) {
        final EnumMap<Type, Boolean> map = new EnumMap<>(Type.class);
        map.put(Type.UserWritable, writable);
        if (!ownerOnly) {
            map.put(Type.GroupWritable, writable);
            map.put(Type.OtherWritable, writable);
        }
        return this.computeNewPermissions(map);
    }
}
