package com.atlassian.stash.internal.user;

import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.stash.internal.ApplicationConstants;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;

/**
 * Model class for mapping a permission to a weight.
 * <p>
 * <b>This model class is not intended to be used outside of Hibernate.</b> {@link Permission} already manages its own
 * {@link Permission#getWeight() weight}, and all code should rely on those values. However, in order to allow certain
 * calculations, such as determining the "highest" permission for a user or group, to be performed in the database more
 * efficiently, the database needs a concept of weight as well. That means Hibernate needs a model class, allowing the
 * construction of queries which join to that data.
 * <p>
 * This entity class has been marked as {@code Immutable}, indicating that Hibernate should not allow instances of it
 * to be updated. Also, no DAO has been implemented for it. All updates to the weights should be done using Liquibase
 * changesets. See {@code liquibase/r1_1/m04.xml} for creation/population of the associated table.
 * <p>
 * Because this class is intended to be a database representation of {@link Permission}, its ID is not generated. It
 * must be set when the instance is constructed, and it is set from the {@link Permission#getId() permission ID}.
 */
@Cacheable
@Entity
@Table(name = InternalPermissionType.TABLE)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@org.hibernate.annotations.Immutable
public class InternalPermissionType {

    public static final String TABLE = "sta_permission_type";

    @Id //Not generated
    @Column(name = "perm_id")
    private final int id;

    @Column(name = "perm_weight", nullable = false, unique = true)
    private final int weight;

    @SuppressWarnings("unused") //Used by Hibernate
    public InternalPermissionType() {
        id = ApplicationConstants.UNSAVED_ENTITY;
        weight = ApplicationConstants.UNSAVED_ENTITY;
    }

    @SuppressWarnings("unused") //Actually not used, at the moment, but will be later
    public InternalPermissionType(Permission permission) {
        id = permission.getId();
        weight = permission.getWeight();
    }

    public int getId() {
        return id;
    }

    public int getWeight() {
        return weight;
    }
}
