/*
 * 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.nifi.registry.security.authorization;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;

/**
 * A group that users can belong to.
 */
public class Group {

    private final String identifier;

    private final String name;

    private final Set<String> users;

    private Group(final Builder builder) {
        this.identifier = builder.identifier;
        this.name = builder.name;
        this.users = Collections.unmodifiableSet(new HashSet<>(builder.users));

        if (this.identifier == null || this.identifier.trim().isEmpty()) {
            throw new IllegalArgumentException("Identifier can not be null or empty");
        }

        if (this.name == null || this.name.trim().isEmpty()) {
            throw new IllegalArgumentException("Name can not be null or empty");
        }
    }

    /**
     * @return the identifier of the group
     */
    public String getIdentifier() {
        return identifier;
    }

    /**
     * @return the name of the group
     */
    public String getName() {
        return name;
    }

    /**
     * @return an unmodifiable set of user identifiers that belong to this group
     */
    public Set<String> getUsers() {
        return users;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }

        final Group other = (Group) obj;
        return Objects.equals(this.identifier, other.identifier);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(this.identifier);
    }

    @Override
    public String toString() {
        return String.format("identifier[%s], name[%s]", getIdentifier(), getName());
    }


    /**
     * Builder for creating Groups.
     */
    public static class Builder {

        private String identifier;
        private String name;
        private Set<String> users = new HashSet<>();
        private final boolean fromGroup;

        public Builder() {
            this.fromGroup = false;
        }

        /**
         * Initializes the builder with the state of the provided group. When using this constructor
         * the identifier field of the builder can not be changed and will result in an IllegalStateException
         * if attempting to do so.
         *
         * @param other the existing access policy to initialize from
         */
        public Builder(final Group other) {
            if (other == null) {
                throw new IllegalArgumentException("Provided group can not be null");
            }

            this.identifier = other.getIdentifier();
            this.name = other.getName();
            this.users.clear();
            this.users.addAll(other.getUsers());
            this.fromGroup = true;
        }

        /**
         * Sets the identifier of the builder.
         *
         * @param identifier the identifier
         * @return the builder
         * @throws IllegalStateException if this method is called when this builder was constructed from an existing Group
         */
        public Builder identifier(final String identifier) {
            if (fromGroup) {
                throw new IllegalStateException(
                        "Identifier can not be changed when initialized from an existing group");
            }

            this.identifier = identifier;
            return this;
        }

        /**
         * Sets the identifier of the builder to a random UUID.
         *
         * @return the builder
         * @throws IllegalStateException if this method is called when this builder was constructed from an existing Group
         */
        public Builder identifierGenerateRandom() {
            if (fromGroup) {
                throw new IllegalStateException(
                        "Identifier can not be changed when initialized from an existing group");
            }

            this.identifier = UUID.randomUUID().toString();
            return this;
        }

        /**
         * Sets the identifier of the builder with a UUID generated from the specified seed string.
         *
         * @return the builder
         * @throws IllegalStateException if this method is called when this builder was constructed from an existing Group
         */
        public Builder identifierGenerateFromSeed(final String seed) {
            if (fromGroup) {
                throw new IllegalStateException(
                        "Identifier can not be changed when initialized from an existing group");
            }
            if (seed == null) {
                throw new IllegalArgumentException("Cannot seed the group identifier with a null value.");
            }

            this.identifier = UUID.nameUUIDFromBytes(seed.getBytes(StandardCharsets.UTF_8)).toString();
            return this;
        }

        /**
         * Sets the name of the builder.
         *
         * @param name the name
         * @return the builder
         */
        public Builder name(final String name) {
            this.name = name;
            return this;
        }

        /**
         * Adds all users from the provided set to the builder's set of users.
         *
         * @param users a set of users to add
         * @return the builder
         */
        public Builder addUsers(final Set<String> users) {
            if (users != null) {
                this.users.addAll(users);
            }
            return this;
        }

        /**
         * Adds the given user to the builder's set of users.
         *
         * @param user the user to add
         * @return the builder
         */
        public Builder addUser(final String user) {
            if (user != null) {
                this.users.add(user);
            }
            return this;
        }

        /**
         * Removes the given user from the builder's set of users.
         *
         * @param user the user to remove
         * @return the builder
         */
        public Builder removeUser(final String user) {
            if (user != null) {
                this.users.remove(user);
            }
            return this;
        }

        /**
         * Removes all users from the provided set from the builder's set of users.
         *
         * @param users the users to remove
         * @return the builder
         */
        public Builder removeUsers(final Set<String> users) {
            if (users != null) {
                this.users.removeAll(users);
            }
            return this;
        }

        /**
         * Clears the builder's set of users so that users is non-null with size 0.
         *
         * @return the builder
         */
        public Builder clearUsers() {
            this.users.clear();
            return this;
        }

        /**
         * @return a new Group constructed from the state of the builder
         */
        public Group build() {
            return new Group(this);
        }

    }

}
