package com.atlassian.stash.internal.user;

import com.atlassian.bitbucket.permission.Permission;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * PermissionGraph that composes two other graphs. The composite graph grants a permission iff one or both of the
 * wrapped graphs grants the permission.
 */
public class CompositePermissionGraph implements PermissionGraph {

    private static final PermissionGraph EMPTY = new PermissionGraph() {
        @Override
        public boolean isGranted(Permission permission, @Nullable Object resource) {
            return false;
        }
    };

    private final PermissionGraph graph1;
    private final PermissionGraph graph2;

    public CompositePermissionGraph(@Nonnull PermissionGraph graph1, @Nonnull PermissionGraph graph2) {
        this.graph1 = checkNotNull(graph1, "graph1");
        this.graph2 = checkNotNull(graph2, "graph2");
    }

    @Nonnull
    public static PermissionGraph maybeCompose(@Nullable PermissionGraph graph1, @Nullable PermissionGraph graph2) {
        if (graph1 == null && graph2 == null) {
            return EMPTY;
        }
        if (graph1 == null) {
            return graph2;
        }
        if (graph2 == null) {
            return graph1;
        }
        return new CompositePermissionGraph(graph1, graph2);
    }


    @Override
    public boolean isGranted(@Nonnull Permission permission, @Nullable Object resource) {
        return graph1.isGranted(permission, resource) || graph2.isGranted(permission, resource);
    }

    @Override
    public String toString() {
        return "{CompositePermissionGraph graph1:" + graph1 + ", graph2:" + graph2 + "}";
    }
}
